Tag for the WSS4J 1.5.0 release
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..4dd9541
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry excluding="**/secconv/ping/**|**/secconv/scenarios/ping/**" kind="src" path="test"/>
+	<classpathentry excluding="**/ping/*.java" kind="src" path="interop"/>
+	<classpathentry excluding="**/oasis/*.java|**/oasis/*.wsdd|**/secconv/*.wsdd|**/secconv/WSConvScenario1.java" kind="src" path="build/work"/>
+	<classpathentry kind="src" path="samples"/>
+	<classpathentry kind="lib" path="lib/addressing-1.0.jar"/>
+	<classpathentry kind="lib" path="lib/axis-1.2.1.jar"/>
+	<classpathentry kind="lib" path="lib/axis-ant-1.2.1.jar"/>
+	<classpathentry kind="lib" path="lib/axis-jaxrpc-1.2.1.jar"/>
+	<classpathentry kind="lib" path="lib/axis-saaj-1.2.1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
+	<classpathentry kind="lib" path="lib/commons-discovery-0.2.jar"/>
+	<classpathentry kind="lib" path="lib/commons-httpclient-3.0-rc2.jar"/>
+	<classpathentry kind="lib" path="lib/commons-logging-1.0.4.jar"/>
+	<classpathentry kind="lib" path="lib/junit-3.8.1.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-1.2.9.jar"/>
+	<classpathentry kind="lib" path="lib/wsdl4j-1.5.1.jar"/>
+	<classpathentry kind="lib" path="lib/xalan-2.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/serializer-2.7.0.jar"/>
+	<classpathentry kind="lib" path="endorsed/xercesImpl.jar"/>
+	<classpathentry kind="lib" path="endorsed/xml-apis.jar"/>
+	<classpathentry kind="lib" path="lib/opensaml-1.0.1.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/xmlsec-1.3.0.jar"/>
+	<classpathentry kind="lib" path="lib/bcprov-jdk13-129.jar"/>
+	<classpathentry kind="lib" path="lib/policy.jar"/>
+	<classpathentry kind="lib" path="/JuiCE/dist/juice.jar"/>
+	<classpathentry kind="output" path="build/classes"/>
+</classpath>
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..65c49aa
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,6 @@
+build
+target
+build.properties
+junit*.properties
+*.log
+*.wsdd
diff --git a/.project b/.project
new file mode 100644
index 0000000..be83598
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>wss4j-svn</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..34502df
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,5 @@
+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+This product includes software Copyright University of Southampton IT

+Innovation Centre, 2006 (http://www.it-innovation.soton.ac.uk).

diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..1c0e89c
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,188 @@
+* What is WSS4J? *
+
+WSS4J is part of the Apache Web Services project. The link to all  Apache Web 
+Service projects:
+http://ws.apache.org/
+
+Apache WSS4J is an implementation of the OASIS Web Services Security specifications
+(WS-Security, WSS) from OASIS Web Services Security TC. WSS4J is primarily
+a Java library that can be used to sign, verify, encrypt, and decrypt SOAP Messages
+according to the WS-Security specifications. WSS4J uses Apache Axis and other Apache 
+XML-Security projects and is interoperable with other JAX-RPC based server/clients 
+and .Net WSE server/clients that follow the OASIS WSS specifications
+
+* Supported WSS Specifications *
+
+WSS4J implements
+
+ * OASIS Web Serives Security: SOAP Message Security 1.0 Standard 200401, 
+   March 2004
+    * Username Token profile V1.0
+    * X.509 Token Profile V1.0
+
+The Web Services Security part of WSS4J is fairly well tested and many
+WebService projects use it already. Also interoperability with
+various other implementations is well tested.
+
+* Support of older WSS specifications *
+
+The WSS4J release 1.1.0 is the last release that was able to emulate previous 
+WSS specs
+
+The next WSS4J releases (>= 1.5.x)
+- support the OASIS V1.0 specs and the relevant namespaces only
+- support one versions of provisional (draft) namespaces for the upcoming version
+
+After the next version of the WSS specs is finished, we do one WSS4J release 
+with the provisional namespaces and another release (with a new release 
+number) with the then fixed namespace URIs. Doing so we could save a lot of
+coding while retaining some backward compatibility using the n-1 release.
+
+
+* Web Services Security Features *
+
+WSS4J can generate and process the following SOAP Bindings:
+
+    o XML Security
+         + XML Signature
+         + XML Encryption
+    o Tokens
+         + Username Tokens
+         + Timestamps
+         + SAML Tokens
+
+WSS4J supports X.509 binary certificates and certificate paths.
+
+The master link to WSS4J: http://ws.apache.org/wss4j/
+
+There is also a Wiki concering Apache WS projects and WSS4J as one
+of the WS sub-projects:
+    http://wiki.apache.org/ws/
+    http://wiki.apache.org/ws/FrontPage/WsFx
+	
+
+WS-Trust and WS-Secure Conversation specifications
+
+WSS4J now comes with the support for derived key token signature and encryption.
+This is used by the Axis2-"rahas" module to provide the WS-Secure Conversation.
+
+WS-Trust support is also being developed within Axis2 based on WSS4J
+
+org.apache.ws.sandbox. package contains experimental implementations of these 
+specifications.
+
+* Installation (binary distribution) *
+
+The WSS4J zip archive is the binary distribution and contains the wss4j
+jar file, some examples, test classes (incl. sources), the interop test
+classes (incl. sources and necessary certificate store), and the according
+client and server deployment and protery files.
+
+The WSS4J jar file contains all classes that implement the basic functions
+and the handlers. To install it make sure this jar file is in the classpath
+of your Axis client and/or Axis server. 
+
+In addition you need to set up the property files that contain information
+about the certificate keystores you use. The property files and the keystore
+are accessed either as resources via classpath or, if that fails, as files
+using the relative path of the application
+
+Thus no specific installation is required. The wss4j-1.5.0.jar file could be 
+included into ear or war files of enterprise or web application servers.
+
+Please refer to the JAVADOC files of the distribution for further 
+information how to use WSS4J, the handlers, and how to setup the
+deployment files.
+
+
+* Required software *
+
+To work with WSS4J you need additional software. Most of the software is also
+needed by your SOAP base system, e.g. Apache Axis. 
+
+To simplify installation and operation of WSS4J an additional ZIP file 
+is provided that holds all other JARs that are required by WSS4J. Please 
+note that we probably not use the very latest versions of these JARs, but 
+we used them during the tests.
+
+To implement the Web Service Security (WSS) part specific software is 
+required:
+
+addressing-1.0.jar
+    This jar contains the implementation of WS-Adressing, required
+    by WSS4J Trust.
+
+    See: http://ws.apache.org/addressing/
+
+axis-1.4.jar
+axis-ant-1.4.jar
+axis-jaxrpc-1.4.jar
+axis-saaj-1.4.jar
+    These jars contain the Apache Axis base software. They implement
+    the basic SOAP processing, deployment, WSDL to Java, Java to WSDL
+    tools and a lot more. Plase refer to a Axis documentation how to
+    setup Axis. You should be familiar with Axis, its setup, and 
+    deployment methods before you start with any WSS4J functions.
+    
+    See: http://ws.apache.org/axis/
+
+bcprov-jdk13-132.jar
+    This is the BouncyCastle library that implements all necessary
+    encryption, hashing, certifcate, and keystore functions. Without
+    this fanatstic library WSS4J wouldn't work at all.
+    
+    See: http://www.bouncycastle.org/
+    
+commons-codec-1.3.jar
+commons-discovery-0.2.jar
+commons-httpclient-3.0-rc2.jar
+commons-logging-1.0.4.jar
+    These jars are from the Commons project and provide may useful 
+    funtions, such as Base64 encoding/decoding, resource lookup,
+    and much more. Please refer to the commons project to get more
+    information.
+    
+    The master link for the commons project:
+    http://jakarta.apache.org/commons/index.html
+
+junit-3.8.1.jar
+    The famous unit test library. Required if you like to build WSS4J
+    from source and run the unit tests.
+    
+    See: http://www.junit.org/
+    
+log4j-1.2.9.jar
+    The logging library. Required to control the logging, error 
+    reporting and so on.
+    
+    See: http://logging.apache.org/
+
+opensaml-1.0.1.jar
+    The SAML implemetation used by WSS4J to implement the SAML profile.
+    
+    See: http://www.opensaml.org/
+
+wsdl4j-1.5.1.jar
+    The WSDL parsing functions, required by Axis tools to read and
+    parse WSDL.
+    
+    See: http://ws.apache.org/axis/  under related projects
+    
+xalan-2.7.0.jar
+    Library that implements XML Path Language (XPath) and XSLT. The XML 
+    Security implementation needs several functions of Xalan XPath.
+   
+    See: http://xml.apache.org/xalan-j/
+   
+xmlsec-1.2.1.jar
+    This library implements the XML-Signature Syntax and Processing and
+    the XML Encryption Syntax and Processing specifications of the W3C. Thus
+    they form one of the base foundations of WSS4J.  
+    
+    See: http://xml.apache.org/security/
+    
+xercesImpl.jar
+xml-apis.jar
+    The XML parser implementation. Required by anybody :-) .
+
+    See: http://xml.apache.org/xerces2-j/
diff --git a/build.properties.sample b/build.properties.sample
new file mode 100644
index 0000000..cff9c49
--- /dev/null
+++ b/build.properties.sample
@@ -0,0 +1,8 @@
+# To enable the use of proxy settings Replace XXXXX 

+# with your environment information and remove the '#' 

+# at the beginning of each line below.

+#http.proxyHost=XXXXX

+#http.proxyPort=XXXXX

+#http.nonProxyHosts=localhost|127.0.0.1

+#http.proxyUser=XXXXX

+#http.proxyPassword=XXXX

diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..5e2ceb6
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,844 @@
+<?xml version="1.0"?>
+
+<project name="Web Services Security (WSS4J)" default="usage" basedir=".">
+    <!-- ================================================================== -->
+    <description>
+   Build file for WSS4J
+
+   This file is intended for ANT, a Java based build tool.
+   ANT is available from http://jakarta.apache.org/ant/index.html
+
+Prerequisites:
+	See the README file
+
+Build Instructions:
+   To build, run
+
+     ant "target"
+
+   on the directory where this file is located with the target you want.
+
+    </description>
+
+    <target name="init">
+        <property name='product.Name' value='Apache-WS-Security-J'/>
+        <property name='product.name' value='wss4j'/>
+        <property name='product.shortname' value='wss4j'/>
+
+        <property name='product.version.major' value='1'/>
+        <property name='product.version.minor' value='5'/>
+        <property name='product.version.level' value='0'/>
+        <!--<property name='product.version' value='${product.version.major}.${product.version.minor}.${product.version.level}'/> -->
+    	<property name='product.version' value='SNAPSHOT'/>
+        <property name="year" value="2005"/>
+        <property name="copyright" value="Copyright &#169; ${year} Apache WSS4J Project. All Rights Reserved."/>
+
+        <!-- Give user a chance to override without editing this file
+             (and without typing -D each time it compiles it) -->
+        <property file="./build.properties"/>
+        <property file="${user.home}/build.properties"/>
+
+        <!-- Place Holder for proxy settings -->
+        <property name="http.proxyHost" value=""/>
+        <property name="http.proxyPort" value=""/>
+        <property name="http.nonProxyHosts" value="localhost"/>
+        <property name="http.proxyUser" value=""/>
+        <property name="http.proxyPassword" value=""/>
+
+        <property name="dir.doc" value="./doc"/>
+        <property name="dir.dist" value="./dist"/>
+        <property name="dir.libs" value="./lib"/>
+        <property name="dir.endorsed.libs" value="./endorsed"/>
+        <property name="dir.src" value="./src"/>
+        <property name="dir.samples" value="./samples"/>
+        <property name="dir.test" value="./test"/>
+        <property name="dir.keys" value="./keys"/>
+        <property name="dir.specs" value="./specs"/>
+        <property name="dir.interop" value="./interop"/>
+        <property name="dir.webapp" location="./webapps/axis" />
+
+        <property name="build.dir" value="./build"/>
+        <property name="build.classes" value="${build.dir}/classes"/>
+        <property name="build.work" value="${build.dir}/work"/>
+        <property name="build.webapp" location="${build.dir}/webapps/axis"/>
+
+        <property name="jar.library" value="${product.shortname}-${product.version}.jar"/>
+
+        <property name="build.doc" value="${build.dir}/doc"/>
+        <property name="build.doc.xml" value="${build.doc}/xml"/>
+        <property name="build.doc.html" value="${build.doc}/html"/>
+        <property name="build.javadoc" value="${build.doc.html}/api"/>
+        <property name="build.junit.xml" value="${build.doc.xml}/junit"/>
+        <property name="build.junit.html" value="${build.doc.html}/junit"/>
+
+
+        <condition property="jdk13.present">
+          <equals arg1="${ant.java.version}" arg2="1.3"/>
+        </condition>
+
+        <condition property="jdk14.present">
+          <equals arg1="${ant.java.version}" arg2="1.4"/>
+        </condition>
+
+        <condition property="jdk15.present">
+          <equals arg1="${ant.java.version}" arg2="1.5"/>
+        </condition>
+
+        <condition property="merlin.ok">
+            <or>
+                <equals arg1="${ant.java.version}" arg2="1.4"/>
+                <equals arg1="${ant.java.version}" arg2="1.5"/>
+            </or>
+        </condition>
+
+        <!-- 
+
+         for the time being following path id uses the libs in the wss4j
+         lib directory only This is done to test if we really don't need
+         any axis libs. After this is done we can include the
+         java.class.path and leave the wss4j/lib empty. This requires that
+         the CLASSPATH includes all required packages (see above
+
+         -->
+    	
+    	
+        <path id="classpath.libraries" description="3rd party libs">
+            <fileset dir="${dir.libs}">
+                <include name="**/*.jar"/>
+                <exclude name="**/bcprov-jdk15-*.jar" unless="jdk15.present"/>
+                <exclude name="**/bcprov-jdk13-*.jar" if="jdk15.present" />
+                <!-- <pathelement path="${java.class.path}"/> -->
+            </fileset>
+            <fileset dir="${dir.endorsed.libs}">
+                <include name="**/*.jar"/>
+                <!-- <pathelement path="${java.class.path}"/> -->
+            </fileset>
+        </path>
+
+        <path id="classpath.wss4j" description="wss4j classes; first try pure class files, then jars">
+            <pathelement path="${build.classes}"/>
+            <pathelement path="${build.dir}/${jar.library}"/>
+        </path>
+
+        <path id="classpath.library">
+            <path refid="classpath.wss4j"/>
+            <path refid="classpath.libraries"/>
+        </path>
+
+        <taskdef resource="axis-tasks.properties" classpathref=
+              "classpath.library"/>
+        <taskdef name="runaxisfunctionaltests" classname=
+              "org.apache.axis.tools.ant.axis.RunAxisFunctionalTestsTask"
+            loaderref="axis">
+            <classpath refid="classpath.library"/>
+        </taskdef>
+      
+        <!-- this shall include Axis jars because the tests use the
+         Axis implementation of javax.xml.soap, etc. Therefore the
+         CLASSPATH is included.
+         -->
+        <path id="classpath.test">
+            <!-- classpath for test is librarypath plus junit -->
+            <path refid="classpath.library"/>
+<!--            <pathelement path="${java.class.path}"/> -->
+        </path>
+
+        <path id="classpath.test.jar">
+            <!-- classpath for test is librarypath plus junit -->
+            <path refid="classpath.library"/>
+            <pathelement path="${build.dir}/${jar.library}"/>
+            <pathelement path="${build.dir}/${jar.tests}"/>
+        </path>
+
+        <patternset id="distFiles">
+            <include name="build.xml"/>
+            <include name="LICENSE.txt"/>
+        </patternset>
+
+        <patternset id="srcFiles">
+         <!-- for some strange reasons, I can't use ${src} but must use src -->
+            <include name="src/**/*"/>
+        </patternset>
+
+        <patternset id="srcSamplesFiles">
+            <include name="samples/**/*"/>
+        </patternset>
+
+        <patternset id="srcUnitTestsFiles">
+            <include name="test/**/*"/>
+        </patternset>
+
+        <patternset id="srcInteropFiles">
+            <include name="interop/**/*"/>
+        </patternset>
+
+        <property name="javadoc.packages"
+            value="
+org.apache.ws.security,
+org.apache.ws.security.components,
+org.apache.ws.security.components.crypto,
+org.apache.ws.security.message,
+org.apache.ws.security.message.token,
+org.apache.ws.security.util,
+org.apache.ws.axis,
+org.apache.ws.axis.security,
+org.apache.ws.axis.security.util
+"/>
+
+      <echo level="debug">
+        -------------------------------------------------------------------
+        ${product.Name} v${product.version} [${year}] 
+        -------------------------------------------------------------------
+        Building with ${ant.version}
+        using build file ${ant.file}
+        Java ${java.version} located at ${java.home} 
+        -------------------------------------------------------------------
+        --- Property values ---
+        sun.boot.class.path=${sun.boot.class.path}
+      </echo>
+      <pathconvert targetos="windows" property="classpath.test.as.string" 
+          refid="classpath.test"/>
+      <echo level="debug">
+        classpath.test: ${classpath.test.as.string}
+      </echo>
+    </target>
+
+    <target name="usage" depends="init">
+      <echo>
+         Build instructions                                                
+        -------------------------------------------------------------------
+                                                                           
+         available targets are:                                            
+                                                                           
+           compile         --> compiles everything                         
+           compile.library --> compiles the source code                    
+           compile.samples --> compiles the samples source code            
+           compile.tests   --> compiles the tests source code              
+           compile.interops--> compiles the interop source code            
+                                                                           
+           javadoc         --> generates the API documentation             
+                               (needs Java > 1.2)                          
+                                                                           
+           test            --> runs the defined JUnit tests                
+           report          --> generates html report of test results       
+                                                                           
+           clean           --> cleans up all generated files and           
+                               directories                                 
+           jar             --> creates the JAR file                        
+           gump            --> includes javadoc, compile jar and test      
+                                                                           
+           usage           --> provides help on using the build tool       
+                               (default)                                   
+                                                                           
+           changelog       --> generates changelog.html                    
+                                                                           
+         See comments inside the build.xml file for more details.          
+        -------------------------------------------------------------------
+      </echo>
+    </target>
+
+    <target name="clean" depends="init"
+        description="Clean up all temporary build files">
+        <delete dir="${build.dir}"/>
+        <delete>
+            <fileset dir="." includes="before*.xml"/>
+            <fileset dir="." includes="after*.xml"/>
+            <fileset dir="." includes="signed*.xml"/>
+            <fileset dir="." includes="server*.wsdd"/>
+            <fileset dir="." includes="client*.wsdd"/>
+        </delete>
+        <delete dir="${dir.dist}"/>
+    </target>
+
+    <target name="prepare" depends="init"
+        description="This target generates a first build directory and checks for some libraries">
+        <tstamp/>
+        <mkdir dir="${build.dir}"/>
+        <delete dir="${build.dir}/test-reports"/>
+        <mkdir dir="${build.dir}/test-reports"/>
+
+        <available property="junit.present" 
+                classname="junit.framework.TestCase">
+            <!-- check whether JUnit is available -->
+            <classpath refid="classpath.test"/>
+        </available>
+
+        <available property="bc.present" classname="org.bouncycastle.jce.provider.BouncyCastleProvider">
+            <!-- check whether BouncyCastle is available -->
+            <classpath refid="classpath.test"/>
+        </available>
+
+        <echo level="debug">
+        --- Flags (Note: If the {property name} is displayed,
+                   then the component is not present)
+        jdk13.present=${jdk13.present}
+        jdk14.present=${jdk14.present}
+        jdk15.present=${jdk15.present}
+        bc.present=${bc.present}
+        </echo>
+
+    </target>
+
+    <!-- ################################################################## -->
+    <!-- ################################################################## -->
+    <!-- ################################################################## -->
+    <!-- ################################################################## -->
+    <!-- ################################################################## -->
+
+    <target name="prepare-src" depends="prepare" 
+    	description="This target copies the Java sources and brands the version information">
+        <!-- create directories -->
+        <mkdir dir="${build.classes}"/>
+    </target>
+
+    <target name="javadoc"
+        depends="prepare-src"
+        description="Generates javadoc from all .java files; this is done on the 'branded' files">
+        <mkdir dir="${build.doc}"/>
+        <mkdir dir="${build.doc.html}"/>
+        <mkdir dir="${build.javadoc}"/>
+
+        <javadoc destdir="${build.javadoc}"
+            packagenames="${javadoc.packages}"
+            classpathref="classpath.test">
+            <!-- additionalparam="-breakiterator"-->
+            <sourcepath>
+                <pathelement location="${dir.src}"/>
+                <pathelement location="${dir.test}"/>
+                <pathelement location="${dir.samples}"/>
+                <pathelement location="${dir.interop}"/>
+            </sourcepath>
+        </javadoc>
+    </target>
+
+    <!-- ################################################################## -->
+
+    <!-- Aliases -->
+    <target name="javadocs" depends="javadoc"/>
+    <target name="jars" depends="jar"/>
+
+    <!-- Collections -->
+    <target name="gump" 
+            depends="clean,javadoc,compile,test" 
+            description="Target for the gump run"/>
+
+    <target name="compile" 
+       depends="compile.library,compile.samples, compile.tests, 
+                compile.interops, fix.properties"
+            description="compile everything"/>
+
+    <target name="test"
+            depends="unitTests, systemTests"
+            description="tests everything"/>        
+
+    <!-- ################################################################## -->
+
+    <target name="fix.properties" if="jdk13.present">
+        <replace dir="${build.dir}" value="org.apache.ws.security.components.crypto.BouncyCastle">
+            <include name="**/*.properties"/>
+            <replacetoken>org.apache.ws.security.components.crypto.Merlin</replacetoken>
+        </replace>
+    </target>
+
+    <target name="compile.library" depends="prepare-src">
+        <!-- Compile the java code from ${dir.src} into ${build.classes} -->
+        <javac srcdir="${dir.src}" destdir="${build.classes}" debug="on">
+            <classpath refid="classpath.library"/>
+            <exclude name="**/Merlin.java" unless="merlin.ok"/>
+            <exclude name="**/sandbox/**/*.java" if="jdk13.present" />
+        </javac>
+        <!-- Copy Property files -->
+        <copy todir="${build.classes}">
+            <fileset dir="${dir.src}">
+                <include name="**/*.properties"/>
+                <exclude name="**/axis/**/*.properties"/>
+            </fileset>
+        </copy>
+    </target>
+
+    <target name="compile.tests"
+        depends="compile.interops"
+        if="junit.present">
+
+        <javac srcdir="${dir.test}" destdir="${build.classes}" debug="on">
+            <classpath refid="classpath.test"/>
+<!--            <exclude name="**/secconv/**/*.java"/> -->
+        </javac>
+
+        <mkdir dir="${build.work}"/>
+
+        <javac srcdir="${build.work}" destdir="${build.classes}" debug="on">
+            <classpath refid="classpath.test"/>
+        </javac>
+
+        <!-- Copy Property files -->
+        <copy todir="${build.classes}">
+            <fileset dir="${dir.test}" includes="**/*.properties"/>
+            <fileset dir="${dir.interop}">
+                <include name="**/*.properties"/>
+            </fileset>
+        </copy>
+    </target>
+
+    <target name="compile.samples"
+        depends="compile.library">
+        <!-- Compile the java code from ${dir.src} into ${build.classes} -->
+        <javac srcdir="${dir.samples}"
+            debug="on"
+            source="1.4"
+            destdir="${build.classes}">
+            <classpath refid="classpath.library"/>
+        </javac>
+        <copy todir="${build.classes}">
+            <fileset dir="${dir.src}" includes="**/axis/**/*.properties"/>
+        </copy>
+    </target>
+
+    <target name="compile.interops"
+        depends="compile.library">
+        <ant dir="${dir.interop}"
+            antfile="build.xml"
+            target="compile"
+            inheritAll="false">
+        </ant>
+    </target>
+
+    <target name="systemTests" unless="skip.tests" depends="compile"
+        if="junit.present"
+        description="Runs all JUnit tests">
+        <runaxisfunctionaltests
+            url="http://localhost:8088"
+            httpServerTarget="start-functional-test-http-server"
+            testTarget="allTests"
+            httpStopTarget="stop-functional-test-http-server"/>
+    </target>
+
+    <target name="start-functional-test-http-server" if="junit.present">
+        <echo message="Starting http server."/>
+        <java classname="org.apache.axis.transport.http.SimpleAxisServer" 
+          fork="yes" dir="${build.dir}">
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <classpath refid="classpath.library"/>
+        </java>
+    </target>
+
+    <target name="stop-functional-test-http-server" if="junit.present">
+        <echo message="Stopping http server."/>
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="classpath.library"/>
+            <arg line="quit"/>
+        </java>
+    </target>
+
+    <target name="allTests" depends="sandboxTests, interopTests">
+    </target>
+
+    <target name="interopTests" depends="init">
+        <echo message="Running system tests - BEGIN..."/>
+
+        <path id="undeploy_xml_files">
+            <fileset dir="${build.work}">
+                <include name="**/undeploy.wsdd"/>
+            </fileset>
+        </path>
+        <property name="undeploy_xml_property" refid="undeploy_xml_files"/>
+
+    	<antcall target="deployWSDD" />
+        <junit printsummary="yes"
+            haltonfailure="yes"
+            fork="yes"
+            dir="${basedir}">
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <jvmarg value="-Dhttp.proxyHost=${http.proxyHost}"/>
+            <jvmarg value="-Dhttp.proxyPort=${http.proxyPort}"/>
+            <jvmarg value="-Dhttp.nonProxyHosts=${http.nonProxyHosts}"/>
+            <jvmarg value="-Dhttp.proxyUser=${http.proxyUser}"/>
+            <jvmarg value="-Dhttp.proxyPassword=${http.proxyPassword}"/>
+            <classpath refid="classpath.test"/>
+            <formatter type="xml"/>
+            <batchtest todir="${build.dir}/test-reports">
+                <fileset dir="${build.classes}">
+                    <include name="**/interop/PackageTests.class"/>
+                </fileset>
+            </batchtest>
+        </junit>
+
+        <java classname="org.apache.axis.utils.Admin" fork="true">
+            <classpath refid="classpath.library"/>
+            <arg value="client"/>
+            <arg file=
+               "${build.work}/org/apache/ws/axis/oasis/ping/undeploy.wsdd"/>
+        </java>
+
+	    <junit printsummary="yes"
+            haltonfailure="yes"
+            fork="yes"
+            dir="${basedir}">
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <jvmarg value="-Dhttp.proxyHost=${http.proxyHost}"/>
+            <jvmarg value="-Dhttp.proxyPort=${http.proxyPort}"/>
+            <jvmarg value="-Dhttp.nonProxyHosts=${http.nonProxyHosts}"/>
+            <jvmarg value="-Dhttp.proxyUser=${http.proxyUser}"/>
+            <jvmarg value="-Dhttp.proxyPassword=${http.proxyPassword}"/>
+            <classpath refid="classpath.test"/>
+            <formatter type="xml"/>
+            <batchtest todir="${build.dir}/test-reports">
+                <fileset dir="${build.classes}">
+                    <include name="**/interop/TestJAXRPCHandler.class"/>
+                </fileset>
+            </batchtest>
+        </junit>
+
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="classpath.library"/>
+            <arg line="${undeploy_xml_property}"/>
+        </java>
+        
+        <echo message="Running system tests - END..."/>
+    </target>
+
+    <target name="unitTests" unless="skip.tests" depends="compile">
+        <junit printsummary="yes"
+            haltonfailure="yes"
+            fork="yes"
+            dir="${basedir}">
+            <!-- See if this helps with Gump test failures -->
+            <sysproperty key="build.clonevm" value="true"/>
+
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <jvmarg value="-Dhttp.proxyHost=${http.proxyHost}"/>
+            <jvmarg value="-Dhttp.proxyPort=${http.proxyPort}"/>
+            <jvmarg value="-Dhttp.nonProxyHosts=${http.nonProxyHosts}"/>
+            <jvmarg value="-Dhttp.proxyUser=${http.proxyUser}"/>
+            <jvmarg value="-Dhttp.proxyPassword=${http.proxyPassword}"/>
+            <classpath refid="classpath.test"/>
+            <formatter type="xml"/>
+            <batchtest todir="${build.dir}/test-reports">
+                <fileset dir="${build.classes}">
+                    <include name="**/wssec/PackageTests.class"/>
+                    <include name="**/components/PackageTests.class"/>
+             <!--<include name="**/secconv/components/PackageTests.class"/> -->
+                </fileset>
+            </batchtest>
+        </junit>
+    </target>
+
+    <target name="sandboxTests" depends="compile">
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="classpath.library"/>
+            <arg line="${dir.samples}/org/apache/ws/sandbox/security/trust2/samples/deploy.wsdd"/>
+        </java>
+
+        <junit printsummary="yes"
+            haltonfailure="yes"
+            fork="yes"
+            dir="${basedir}">
+            <!-- See if this helps with Gump test failures -->
+            <sysproperty key="build.clonevm" value="true"/>
+
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <jvmarg value="-Dhttp.proxyHost=${http.proxyHost}"/>
+            <jvmarg value="-Dhttp.proxyPort=${http.proxyPort}"/>
+            <jvmarg value="-Dhttp.nonProxyHosts=${http.nonProxyHosts}"/>
+            <jvmarg value="-Dhttp.proxyUser=${http.proxyUser}"/>
+            <jvmarg value="-Dhttp.proxyPassword=${http.proxyPassword}"/>
+            <classpath refid="classpath.test"/>
+            <formatter type="xml"/>
+            <batchtest todir="${build.dir}/test-reports">
+                <fileset dir="${build.classes}">
+                    <include name="**/sandbox/PackageTests.class"/>
+                </fileset>
+            </batchtest>
+        </junit>
+
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="classpath.library"/>
+            <arg line="${dir.samples}/org/apache/ws/sandbox/security/trust2/samples/undeploy.wsdd"/>
+        </java>
+    </target>
+    
+    <target name="tcpmon" depends="init" description=
+                "Start standalone tcp monitor application (provided by axis)">
+        <java dir="${basedir}" fork="yes" failOnError="true" 
+                 className="org.apache.axis.utils.tcpmon">
+            <classpath refid="classpath.library" />
+             <arg value="9080" />
+             <arg value="localhost" />
+             <arg value="8080" />
+         </java>
+    </target>
+
+	<!--
+	This runs the selected scenario with SimpleAxisServer locally.
+	Before you start this target be sure you have started tcpmon too 
+        in a separate
+	"ant tcpmon" call.
+	To run different scenarios use: "ant -DNumber=x scenarioTest" 
+        to run scenario x
+	-->
+    <target name="scenarioTest" depends="compile"
+        if="junit.present"
+        description="Runs all JUnit tests">
+        <runaxisfunctionaltests
+            url="http://localhost:8088"
+            httpServerTarget="start-functional-test-http-server"
+            testTarget="scenario"
+            httpStopTarget="stop-functional-test-http-server"/>
+    </target>
+
+    <target name="scenario" if="junit.present">
+        <echo message=
+          "Running interop test scenario ${Number} on SimpleAxisServer"/>
+
+    	<antcall target="deployWSDD" />
+    	
+        <java classname="interop.TestScenario${Number}" fork="yes" 
+                 dir="${basedir}">
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+            <classpath refid="classpath.library"/>
+        </java>
+
+    	<antcall target="undeployWSDD" />
+
+    </target>
+	
+	<!--
+	This runs the selected scenario with SimpleAxisServer locally 
+        with perfomance
+	timing switched on.
+	You may also emable the **.TIME entry in log4j.properties to get 
+        the internal
+	timing.
+	To run different scenarios use: "ant -DNumber=x scenarioTest" 
+        to run scenario x
+	-->
+    <target name="performanceTest" depends="compile"
+        if="junit.present"
+        description="Runs all JUnit tests">
+        <runaxisfunctionaltests
+            url="http://localhost:8088"
+            httpServerTarget="start-functional-test-http-server"
+            testTarget="performance"
+            httpStopTarget="stop-functional-test-http-server"/>
+    </target>
+
+    <target name="performance" if="junit.present">
+        <echo message=
+           "Running performance test scenario ${Number} on SimpleAxisServer"/>
+
+    	<antcall target="deployWSDD" />
+        <java classname="interop.TestScenario${Number}" fork="yes" 
+            dir="${basedir}">
+            <jvmarg value="-Djava.endorsed.dirs=${basedir}/endorsed"/>
+       <arg value="-lhttp://localhost:8080/axis/services/Ping${Number}" />
+        	<arg value="-t" />
+            <classpath refid="classpath.library"/>
+        </java>
+    	<antcall target="undeployWSDD" />
+    </target>
+	
+    <target name="deployWSDD">
+      <path id="deploy_xml_files">
+      <fileset dir="${build.work}">
+        <include name="**/deploy.wsdd"/>
+      </fileset>
+      </path>
+
+      <copy todir="${build.dir}/keys">
+        <fileset dir="${dir.keys}" includes="**"/>
+      </copy>
+      <copy todir="${build.dir}/interop">
+        <fileset dir="${dir.interop}" includes="*.jks"/>
+      </copy>
+
+      <property name="deploy_xml_property" refid="deploy_xml_files"/>
+ 
+      <java classname="org.apache.axis.utils.Admin" fork="true">
+        <classpath refid="classpath.library"/>
+        <arg value="client"/>
+        <arg file="${build.work}/org/apache/ws/axis/oasis/Client_deploy.wsdd"/>
+      </java>
+        
+      <java classname="org.apache.axis.client.AdminClient" fork="yes">
+        <classpath refid="classpath.library"/>
+        <arg line="${deploy_xml_property}"/>
+      </java>
+    </target>
+	
+    <target name="undeployWSDD">
+      <path id="undeploy_xml_files">
+        <fileset dir="${build.work}">
+          <include name="**/undeploy.wsdd"/>
+        </fileset>
+      </path>
+
+      <property name="undeploy_xml_property" refid="undeploy_xml_files"/>
+
+      <java classname="org.apache.axis.utils.Admin" fork="true">
+            <classpath refid="classpath.library"/>
+            <arg value="client"/>
+            <arg file=
+                 "${build.work}/org/apache/ws/axis/oasis/ping/undeploy.wsdd"/>
+      </java>
+
+      <java classname="org.apache.axis.client.AdminClient" fork="yes">
+        <classpath refid="classpath.library"/>
+        <arg line="${undeploy_xml_property}"/>
+      </java>
+    </target>
+		
+	<!-- generate a report from all the tests. 
+           requires Xalan or other XSLT engine in ant\lib-->
+
+   <target name="report" depends="init">
+        <junitreport todir="${build.dir}/test-reports">
+            <fileset dir="${build.dir}/test-reports">
+                <include name="TEST-*.xml"/>
+            </fileset>
+            <report format="frames" todir="${build.dir}/test-reports/html"/>
+        </junitreport>
+        <echo message=
+            "point your browser to ${build.dir}/test-reports/html/index.html"/>
+    </target>
+
+    <target name="jar"
+        depends="compile, test"
+        description="Creates the ${jar.library}">
+
+        <jar jarfile="${build.dir}/${jar.library}"
+            basedir="${build.classes}"
+            includes="**/*, *.txt"
+            excludes="components/**, policy/**, *.properties, **/sandbox/**, wssec/**, **/interop/**, **/oasis/**, **/samples/**" 
+            />
+    </target>
+
+   <target name="bindist" depends="gump" 
+      description="Build zip file for distro">
+     <delete dir="${dir.dist}"/>
+     <mkdir dir="${dir.dist}"/>
+     <jar jarfile="${dir.dist}/${jar.library}"
+       basedir="${build.classes}"
+       includes="**/apache/**/security/**"  />
+     <zip destfile=
+        "${dir.dist}/${product.shortname}-bin-${product.version}.zip">
+        <zipfileset prefix="wss4j" dir="."
+          includes="keys/**, interop/**, interop2/**, test/**, samples/**,
+          LICENSE.txt, README.txt legal/**, webapps/**"/>
+        <zipfileset prefix="wss4j/classes" dir="${build.classes}"
+          includes=
+     "*.properties, interop/**, wssec/**, org/**/oasis/**, org/**/samples/**"/>
+        <zipfileset prefix="wss4j/doc/api" dir="${build.javadoc}"/>
+        <zipfileset fullpath="wss4j/${jar.library}" dir="${dir.dist}" 
+          includes="${jar.library}"/>
+      </zip>
+    </target>
+
+    <target name="otherdist" depends="init" 
+             description="Build zip for required jars">
+	     <mkdir dir="${dir.dist}"/>
+	     <zip destfile=
+           "${dir.dist}/${product.shortname}-otherjars-${product.version}.zip">
+	         <zipfileset prefix="wss4j" dir="."
+	             includes="lib/*.jar, endorsed/*.jar"/>
+	     </zip>
+	 </target>	
+	
+	<target name="srcdist" depends="init" description=
+               "Build source zip file for distro">
+        <mkdir dir="${dir.dist}"/>
+        <zip destfile=
+                 "${dir.dist}/${product.shortname}-src-${product.version}.zip">
+            <zipfileset prefix="wss4j" dir="."
+                includes="src/** LICENSE.txt README.txt legal/** build.xml "/>
+        </zip>
+    </target>
+
+    <target name="fixcrlf"
+        description="Fixes CRLF">
+        <fixcrlf srcdir="."
+            eol="crlf"
+            includes="**/*.java"
+            />
+        <fixcrlf srcdir="."
+            eol="crlf"
+            includes="**/*.properties"
+            />
+    </target>
+
+    <target name="changelog"
+        depends="prepare"
+        description="Generate the changelog for WSS4J project">
+        <cvschangelog dir="."
+            destfile="${build.dir}/changelog.xml"
+            />
+        <style in="${build.dir}/changelog.xml"
+            out="${build.dir}/changelog.html"
+            style="./tools/changelog.xsl">
+            <param name="title" expression="WSS4J ChangeLog"/>
+            <param name="module" expression="ws-wss4j"/>
+            <param name="cvsweb" expression="http://cvs.apache.org/viewcvs/"/>
+        </style>
+    </target>
+
+  <!-- =================================================================== -->
+  <!-- Creates a war file for interop testing                              -->
+  <!-- =================================================================== -->
+  <target name="interop-war" depends="test"
+      description="Create the web application" >
+    <mkdir dir="${build.webapp}"/>
+    <copy todir="${build.webapp}">
+      <fileset dir="${dir.webapp}"/>
+    </copy>
+    <copy todir="${build.webapp}/WEB-INF/lib">
+      <fileset dir="${dir.libs}">
+        <include name="*.jar"/>
+      </fileset>
+      <fileset dir="${basedir}/endorsed">
+        <include name="*.jar"/>
+      </fileset>
+    </copy>
+    <copy todir="${build.webapp}/WEB-INF">
+      <fileset dir="${build.dir}">
+        <include name="*.wsdd"/>
+      </fileset>
+    </copy>
+    <copy todir="${build.webapp}/WEB-INF/classes/">
+      <fileset dir="${build.classes}"/>
+    </copy>
+    <copy todir="${build.webapp}/WEB-INF/classes/">
+      <fileset dir=".">
+          <include name="client-config.wsdd"/>
+      </fileset>
+    </copy>
+    <copy todir="${build.webapp}/WEB-INF/classes/interop">
+        <fileset dir="${dir.interop}">
+            <include name="**/interop2.jks"/>
+        </fileset>
+    </copy>
+
+    <delete>
+      <fileset dir="${build.webapp}" includes="**/CVS"/>
+    </delete>
+    <path id="deploy_xml_files">
+        <fileset dir="${build.work}">
+            <include name="**/deploy.wsdd"/>
+        </fileset>
+    </path>
+    <property name="deploy_xml_property" refid="deploy_xml_files"/>
+    <java classname="org.apache.axis.utils.Admin" fork="true"
+        dir="${build.webapp}/WEB-INF/classes">
+      <classpath refid="classpath.library"/>
+      <arg value="client"/>
+      <arg file="${build.work}/org/apache/ws/axis/oasis/Client_deploy.wsdd"/>
+    </java>
+    <java classname="org.apache.axis.utils.Admin" fork="yes" 
+        dir="${build.webapp}/WEB-INF">
+        <classpath refid="classpath.library"/>
+        <arg line="server"/>
+        <arg line="${deploy_xml_property}"/>
+    </java>
+
+    <jar jarfile="${build.dir}/wss4j.war" basedir="${build.webapp}"/>
+  </target>
+
+</project>
diff --git a/endorsed/xercesImpl.jar b/endorsed/xercesImpl.jar
new file mode 100644
index 0000000..eac75ae
--- /dev/null
+++ b/endorsed/xercesImpl.jar
Binary files differ
diff --git a/endorsed/xml-apis.jar b/endorsed/xml-apis.jar
new file mode 100644
index 0000000..243eaea
--- /dev/null
+++ b/endorsed/xml-apis.jar
Binary files differ
diff --git a/interop/WSETEST.cer b/interop/WSETEST.cer
new file mode 100644
index 0000000..1ad4118
--- /dev/null
+++ b/interop/WSETEST.cer
Binary files differ
diff --git a/interop/build.xml b/interop/build.xml
new file mode 100644
index 0000000..a72abfe
--- /dev/null
+++ b/interop/build.xml
@@ -0,0 +1,102 @@
+<project name="Axis_OASIS_Interop" default="compile">
+    <description>
+        generate files from WSDL description, also target to deploy
+        the service in a runing Axis (probably in Tomcat or alike)
+    </description>
+
+    <!-- The following setting assumes that all necessary libs (jars)
+      are located in a lib directory directly under wss4j. First set
+      a reference to the wss4j relative to this working directory -->
+    <property name="dir.wss4j" value="${basedir}/.."/>
+    <property name="dir.interop" value="${dir.wss4j}/interop"/>
+    <property name="dir.work" value="${dir.wss4j}/build/work"/>
+    <property name="dir.classes" value="${dir.wss4j}/build/classes"/>
+    <property name="dir.libs" value="${dir.wss4j}/lib"/>
+
+    <property name="server" value="org/apache/ws/axis/oasis/ping"/>
+    <property name="client" value="org/apache/ws/axis/oasis"/>
+
+    <path id="classpath.libraries" description=" 3rd party and Axis libs">
+        <fileset dir="${dir.libs}">
+            <include name="**/*.jar"/>
+        </fileset>
+    </path>
+
+    <taskdef resource="axis-tasks.properties" classpathref="classpath.libraries"/>
+
+    <target name="clientdeploy">
+        <java classname="org.apache.axis.utils.Admin" fork="true">
+            <classpath refid="classpath.libraries"/>
+            <arg value="client"/>
+            <arg file="${dir.work}/${client}/Client_deploy.wsdd"/>
+        </java>
+    </target>
+
+    <target name="serverdeploy">
+        <java classname="org.apache.axis.client.AdminClient" fork="true">
+            <classpath refid="classpath.libraries"/>
+            <arg file="${dir.work}/${server}/deploy.wsdd"/>
+        </java>
+    </target>
+
+    <target name="serverundeploy">
+        <java classname="org.apache.axis.client.AdminClient" fork="true">
+            <classpath refid="classpath.libraries"/>
+            <arg file="${dir.work}/${server}/undeploy.wsdd"/>
+        </java>
+    </target>
+
+    <target name="chkWsdl">
+      <uptodate property="wsdl.notRequired" 
+        targetfile="${dir.work}/${server}/PingBindingImpl.java"
+        srcfile="${dir.interop}/ping.wsdl"/>
+    </target>
+
+    <target name="wsdl" depends="chkWsdl" unless="wsdl.notRequired">
+      <axis-wsdl2java
+          output="${dir.work}"
+          serverSide="yes"
+          testcase="no"
+          verbose="no"
+          url="${dir.interop}/ping.wsdl">
+          <mapping
+              namespace="http://xmlsoap.org/Ping"
+              package="org.apache.ws.axis.oasis.ping"/>
+      </axis-wsdl2java>
+    </target>
+
+    <target name="init">
+      <mkdir dir="${dir.work}"/>
+    </target>
+
+    <target name="compile" depends="init, wsdl">
+        <copy todir="${dir.work}/${server}" overwrite="yes">
+          <fileset dir="${dir.interop}/${server}">
+            <include name="*.java"/>
+            <include name="*.wsdd"/>
+          </fileset>
+        </copy>
+        <copy todir="${dir.work}/${client}" overwrite="yes">
+          <fileset dir="${dir.interop}/${client}">
+            <include name="*.java"/>
+            <include name="*.wsdd"/>
+          </fileset>
+        </copy>
+        <javac srcdir="${dir.work}" 
+                destdir="${dir.classes}"
+                source="1.4"
+               debug="true">
+          <classpath refid="classpath.libraries" />
+          <include name="${server}/*.java" />
+          <include name="${client}/*.java" />
+        </javac>
+    </target>
+
+    <target name="clean"
+        description="clean up">
+        <delete dir="${dir.work}/${server}"/>
+        <delete dir="${dir.classes}/${server}"/>
+        <delete dir="${dir.work}/${client}"/>
+        <delete dir="${dir.classes}/${client}"/>
+    </target>
+</project>
\ No newline at end of file
diff --git a/interop/interop.jks b/interop/interop.jks
new file mode 100644
index 0000000..c8a34a9
--- /dev/null
+++ b/interop/interop.jks
Binary files differ
diff --git a/interop/interop2.jks b/interop/interop2.jks
new file mode 100644
index 0000000..babac0f
--- /dev/null
+++ b/interop/interop2.jks
Binary files differ
diff --git a/interop/keys/Alice.cer b/interop/keys/Alice.cer
new file mode 100644
index 0000000..a23c79b
--- /dev/null
+++ b/interop/keys/Alice.cer
Binary files differ
diff --git a/interop/keys/Bob.cer b/interop/keys/Bob.cer
new file mode 100644
index 0000000..1b8b8ee
--- /dev/null
+++ b/interop/keys/Bob.cer
Binary files differ
diff --git a/interop/keys/README.txt b/interop/keys/README.txt
new file mode 100644
index 0000000..380c8b7
--- /dev/null
+++ b/interop/keys/README.txt
@@ -0,0 +1,34 @@
+- Certificates and keys are from the Gartner WSS interop show. 
+- Passwords for every private key is 'password' (no quotes). 
+- Bob identity for service and Alice identity for client.
+- The ca.pfx files contains cert and private key for intermediary CA 
+  used to issue Alice and Bob certificates and root.pfx contains cert 
+  and private key for root CA used to issue the intermediary CA 
+  certificate.
+- Conversion tips are from http://mark.foster.cc/kb/openssl-keytool.html
+- Please use JDK1.5 (importing WssIP has problems with JDK1.4)
+
+set CLASSPATH=org.mortbay.jetty-5.1.4rc0.jar;
+
+java org.mortbay.util.PKCS12Import alice.pfx interop2.jks
+keytool -keyclone -keystore interop2.jks -alias 1 -dest alice
+keytool -delete -keystore interop2.jks -alias 1
+
+java org.mortbay.util.PKCS12Import bob.pfx interop2.jks
+keytool -keyclone -keystore interop2.jks -alias 1 -dest bob
+keytool -delete -keystore interop2.jks -alias 1
+
+java org.mortbay.util.PKCS12Import WssIP.pfx interop2.jks
+keytool -keyclone -keystore interop2.jks -alias "wssip's oasis interop test ca id" -dest wssip
+keytool -delete -keystore interop2.jks -alias "wssip's oasis interop test ca id"
+
+java org.mortbay.util.PKCS12Import ca.pfx ca.jks
+java org.mortbay.util.PKCS12Import root.pfx root.jks
+
+keytool -export -alias 1 -keystore root.jks -file root.crt
+keytool -export -alias 1 -keystore ca.jks -file ca.crt
+
+keytool -import -keystore interop2.jks -import -trustcacerts -alias root -file root.crt
+keytool -import -keystore interop2.jks -import -trustcacerts -alias ca -file ca.crt
+
+keytool -list -v -keystore interop2.jks
\ No newline at end of file
diff --git a/interop/keys/WssIP.cer b/interop/keys/WssIP.cer
new file mode 100644
index 0000000..df21df8
--- /dev/null
+++ b/interop/keys/WssIP.cer
Binary files differ
diff --git a/interop/keys/WssIP.pfx b/interop/keys/WssIP.pfx
new file mode 100644
index 0000000..e68c46a
--- /dev/null
+++ b/interop/keys/WssIP.pfx
Binary files differ
diff --git a/interop/keys/alice.pfx b/interop/keys/alice.pfx
new file mode 100644
index 0000000..8d1e2f2
--- /dev/null
+++ b/interop/keys/alice.pfx
Binary files differ
diff --git a/interop/keys/bob.pfx b/interop/keys/bob.pfx
new file mode 100644
index 0000000..4cda657
--- /dev/null
+++ b/interop/keys/bob.pfx
Binary files differ
diff --git a/interop/keys/ca.cer b/interop/keys/ca.cer
new file mode 100644
index 0000000..d73fb39
--- /dev/null
+++ b/interop/keys/ca.cer
Binary files differ
diff --git a/interop/keys/ca.pfx b/interop/keys/ca.pfx
new file mode 100644
index 0000000..7f264a7
--- /dev/null
+++ b/interop/keys/ca.pfx
Binary files differ
diff --git a/interop/keys/root.cer b/interop/keys/root.cer
new file mode 100644
index 0000000..e20d049
--- /dev/null
+++ b/interop/keys/root.cer
Binary files differ
diff --git a/interop/keys/root.pfx b/interop/keys/root.pfx
new file mode 100644
index 0000000..e6d14f3
--- /dev/null
+++ b/interop/keys/root.pfx
Binary files differ
diff --git a/interop/org/apache/ws/axis/oasis/Client_deploy.wsdd b/interop/org/apache/ws/axis/oasis/Client_deploy.wsdd
new file mode 100644
index 0000000..b7f443a
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Client_deploy.wsdd
@@ -0,0 +1,266 @@
+<deployment xmlns="http://xml.apache.org/axis/wsdd/"
+            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+
+ <!--
+ Usage of cert/key identifiers (parameter: user / encryptionUser):
+ For the interop tests we have two different certificate/key pairs:
+ Server certificate: 
+ 	contained in bob.pfx
+ 	identified with: bob
+ Client certificate:
+    contained in alice.pfx
+    identified with: alice
+ 
+ The Server uses it's certificate/private key to sign its request, the client
+ uses the server's certificate/pub key to encrypt requests
+
+ The client uses it's certificate/private key to sign its request, the server 
+ uses the client's certificate/pub key to encrypt responses-
+ -->
+ <!-- define the service, using the WSDoAllSender security handler in request flow -->
+ <service name="Ping1">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="user" value="Chris"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="UsernameToken"/>
+    <parameter name="passwordType" value="PasswordText" />
+   </handler>
+  </requestFlow>
+  </service>
+
+ <service name="Ping2">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="UsernameToken Encrypt"/>
+    <parameter name="user" value="Chris"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="passwordType" value="PasswordText" />
+    <parameter name="addUTElements" value="Nonce Created" />
+    <parameter name="encryptionPropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <!-- Use the Server's cert/key to encrypt the request -->
+    <parameter name="encryptionUser" value="bob" />
+    <parameter name="encryptionParts" 
+      value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken" />  
+   </handler>
+  </requestFlow>
+  </service>
+  
+ <service name="Ping2a">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="UsernameTokenSignature Encrypt Timestamp"/>
+    <parameter name="user" value="Chris"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="encryptionPropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <!-- Use the Server's cert/key to encrypt the request -->
+    <parameter name="encryptionUser" value="bob" />
+    <parameter name="encryptionParts" 
+      value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken" />  
+   </handler>
+  </requestFlow>
+  </service>
+
+ <service name="Ping3">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <!-- Use the Client's cert/key to sign the request -->
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <parameter name="encryptionUser" value="bob" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </responseFlow>
+ </service>
+
+ <service name="Ping4">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <!-- Use the Client's cert/key to sign the request -->
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="EmbeddedKeyName" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
+    <parameter name="EmbeddedKeyCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1" />
+    <parameter name="EmbeddedKeyName" value="SessionKey" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </responseFlow>
+  
+  </service>
+
+ <service name="Ping5">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature NoSerialization"/>
+    <!-- Use the Client's cert/key to sign the request -->
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="signatureParts" value="{}{http://xmlsoap.org/Ping}ticket" />    
+   </handler>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Timestamp"/>
+    <!-- Use the Client's cert/key to sign the request -->
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>  
+  </requestFlow>
+  </service>
+
+ <service name="Ping6">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Encrypt Signature Timestamp"/>
+    <!-- Use the Client's cert/key to sign the request -->
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <!-- Use the Server's cert/key to encrypt the request -->
+    <parameter name="encryptionUser" value="bob" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Encrypt Signature Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </responseFlow>
+  </service>
+
+
+ <service name="Ping7">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="user" value="alice"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signatureParts"
+      value="{}{http://schemas.xmlsoap.org/soap/envelope/}Body;STRTransform" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <parameter name="encryptionUser" value="bob" />
+    <parameter name="encryptionPropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="decryptionPropFile" value="wsstest.properties" />
+   </handler>
+  </responseFlow>
+  </service>
+
+ <service name="STPing1">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Timestamp SAMLTokenUnsigned"/>
+    <parameter name="samlPropFile" value="saml.properties"/>
+    
+   </handler>
+  </requestFlow>
+  </service>
+  
+  <!--
+    The saml3.properties file defines a SAML token with "sender vouches"
+    option. Thus no further user specific data is required here. The
+    SAML issuer takes all the data from its data store (for the bare bone
+    SAML issuer included here: these data is in the saml properties file).
+    The SAML issuer uses its own certificate to sign, own certificate store,
+    etc.
+    
+    The DoAllSender then gets the issuer's data (key name, key password)
+    and forwards it to the SignEnvelope. The SignEnvelope now signs the
+    SAML token _and_ at least one part of the message (SOAP Body if nothing
+    was specified, or the specified part).
+   --> 
+   <service name="STPing3">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Timestamp SAMLTokenSigned"/>
+    <parameter name="samlPropFile" value="saml3.properties"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+   </handler>
+  </requestFlow>
+  </service>
+  
+  <!--
+    The saml4.properties file defines a SAML token with "holder-of-key"
+    option. Because the DoAllSender handler acts as both, user and requestor,
+    we need the user specific data here. The handler gets this information,
+    forwards it to our (bare bone) SAML issuer. The SAML issuer creates
+    the SAML token and includes the user's certificate, and signs the
+    whole token with its certificate / Private Key.
+    
+    DoAllSender forwards the user's information to SignEnvelope that uses
+    this to sign the message (SOAP Body if nothing was specified, or the 
+    specified part). Because the issuer signed the SAML token the user's
+    certificate (contained in the token) can be trusted.
+   --> 
+   <service name="STPing4">
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Timestamp SAMLTokenSigned"/>
+    <parameter name="samlPropFile" value="saml4.properties"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback"/>
+    <parameter name="signaturePropFile" value="crypto.properties" />    
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+   </handler>
+  </requestFlow>
+  </service>
+  
+ <transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender"/>
+ <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
+ <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender"/>
+  
+  
+ </deployment>
diff --git a/interop/org/apache/ws/axis/oasis/PWCallback.java b/interop/org/apache/ws/axis/oasis/PWCallback.java
new file mode 100644
index 0000000..d2302b3
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/PWCallback.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ */
+package org.apache.ws.axis.oasis;
+
+import org.apache.ws.security.WSPasswordCallback;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.IOException;
+
+/**
+ * Class PWCallback
+ */
+public class PWCallback implements CallbackHandler {
+
+    /** Field key */
+    private static final byte[] key = {
+        (byte) 0x31, (byte) 0xfd, (byte) 0xcb, (byte) 0xda, (byte) 0xfb,
+        (byte) 0xcd, (byte) 0x6b, (byte) 0xa8, (byte) 0xe6, (byte) 0x19,
+        (byte) 0xa7, (byte) 0xbf, (byte) 0x51, (byte) 0xf7, (byte) 0xc7,
+        (byte) 0x3e, (byte) 0x80, (byte) 0xae, (byte) 0x98, (byte) 0x51,
+        (byte) 0xc8, (byte) 0x51, (byte) 0x34, (byte) 0x04,
+    };
+
+    /*
+     * (non-Javadoc)
+     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
+     */
+
+    /**
+     * Method handle
+     * 
+     * @param callbacks 
+     * @throws IOException                  
+     * @throws UnsupportedCallbackException 
+     */
+    public void handle(Callback[] callbacks)
+            throws IOException, UnsupportedCallbackException {
+
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+
+                /*
+                 * here call a function/method to lookup the password for
+                 * the given identifier (e.g. a user name or keystore alias)
+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+                 * for Testing we supply a fixed name here.
+                 */
+                if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {
+                    pc.setKey(key);
+                } else {
+                    pc.setPassword("security");
+                }
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i],
+                        "Unrecognized Callback");
+            }
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/PWCallback1.java b/interop/org/apache/ws/axis/oasis/PWCallback1.java
new file mode 100644
index 0000000..3ff9c01
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/PWCallback1.java
@@ -0,0 +1,214 @@
+/*
+
+ * Copyright  2003-2004 The Apache Software Foundation.
+
+ *
+
+ *  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.
+
+ *
+
+ */
+
+
+
+/**
+
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+
+ */
+
+package org.apache.ws.axis.oasis;
+
+
+
+import org.apache.ws.security.WSPasswordCallback;
+
+
+
+import javax.security.auth.callback.Callback;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import java.io.IOException;
+
+
+
+/**
+
+ * Class PWCallback
+
+ */
+
+public class PWCallback1 implements CallbackHandler {
+
+
+
+    /** Field key */
+
+    private static final byte[] key = {
+
+        (byte) 0x31, (byte) 0xfd, (byte) 0xcb, (byte) 0xda, (byte) 0xfb,
+
+        (byte) 0xcd, (byte) 0x6b, (byte) 0xa8, (byte) 0xe6, (byte) 0x19,
+
+        (byte) 0xa7, (byte) 0xbf, (byte) 0x51, (byte) 0xf7, (byte) 0xc7,
+
+        (byte) 0x3e, (byte) 0x80, (byte) 0xae, (byte) 0x98, (byte) 0x51,
+
+        (byte) 0xc8, (byte) 0x51, (byte) 0x34, (byte) 0x04,
+
+    };
+
+
+
+    /*
+
+     * (non-Javadoc)
+
+     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
+
+     */
+
+
+
+    /**
+
+     * Method handle
+
+     * 
+
+     * @param callbacks 
+
+     * @throws java.io.IOException                  
+
+     * @throws javax.security.auth.callback.UnsupportedCallbackException 
+
+     */
+
+    public void handle(Callback[] callbacks)
+
+            throws IOException, UnsupportedCallbackException {
+
+
+
+        for (int i = 0; i < callbacks.length; i++) {
+
+            if (callbacks[i] instanceof WSPasswordCallback) {
+
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+
+
+
+                /*
+
+                 * This usage type is used only in case we received a
+
+                 * username token with a password of type PasswordText or
+
+                 * an unknown password type.
+
+                 * 
+
+                 * This case the WSPasswordCallback object contains the
+
+                 * identifier (aka username), the password we received, and
+
+                 * the password type string to identify the type.
+
+                 * 
+
+                 * Here we perform only a very simple check.
+
+                 */
+
+                if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
+
+                	if(pc.getIdentifer().equals("Ron") && pc.getPassword().equals("noR")) {
+
+                        return;
+
+                	}
+
+                    if (pc.getPassword().equals("sirhC")) {
+
+                        return;
+
+                    }               	
+
+                    throw new UnsupportedCallbackException(callbacks[i],
+
+                    "check failed");
+
+                }
+
+                /*
+
+                 * here call a function/method to lookup the password for
+
+                 * the given identifier (e.g. a user name or keystore alias)
+
+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+
+                 * for Testing we supply a fixed name here.
+
+                 */
+
+                if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {
+
+                    pc.setKey(key);
+
+                } else if(pc.getIdentifer().equals("alice")) {
+
+                    pc.setPassword("password");
+
+                } else if(pc.getIdentifer().equals("bob")) {
+
+                    pc.setPassword("password");
+
+                } else if(pc.getIdentifer().equals("Ron")) {
+
+                    pc.setPassword("noR");
+
+                } else {
+
+                    pc.setPassword("sirhC");
+
+                }
+
+            } else {
+
+                throw new UnsupportedCallbackException(callbacks[i],
+
+                        "Unrecognized Callback");
+
+            }
+
+        }
+
+    }
+
+}
+
diff --git a/interop/org/apache/ws/axis/oasis/STScenario1.java b/interop/org/apache/ws/axis/oasis/STScenario1.java
new file mode 100644
index 0000000..35aaa7e
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/STScenario1.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario1
+ */
+public class STScenario1 {
+
+    /** Field address */
+    private static final String address =
+            "http://localhost:9080/axis/services/STPing1";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getSTPing1(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - ST Scenario 1 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/STScenario3.java b/interop/org/apache/ws/axis/oasis/STScenario3.java
new file mode 100644
index 0000000..2bcd2ca
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/STScenario3.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario1
+ */
+public class STScenario3 {
+
+    /** Field address */
+    private static final String address =
+            "http://localhost:9080/axis/services/STPing3";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getSTPing3(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - ST Scenario 3 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/STScenario4.java b/interop/org/apache/ws/axis/oasis/STScenario4.java
new file mode 100644
index 0000000..5b7a132
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/STScenario4.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario1
+ */
+public class STScenario4 {
+
+    /** Field address */
+    private static final String address =
+            "http://localhost:9080/axis/services/STPing4";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getSTPing4(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - ST Scenario 4 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario1.java b/interop/org/apache/ws/axis/oasis/Scenario1.java
new file mode 100644
index 0000000..8fd2ae8
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario1.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario1
+ */
+public class Scenario1 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping1";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing1(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 1 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario2.java b/interop/org/apache/ws/axis/oasis/Scenario2.java
new file mode 100644
index 0000000..3c72968
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario2.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario2
+ */
+public class Scenario2 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping2";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing2(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 2 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario2a.java b/interop/org/apache/ws/axis/oasis/Scenario2a.java
new file mode 100644
index 0000000..58495b2
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario2a.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario2a
+ */
+public class Scenario2a {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping2a";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing2a(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 2a text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario3.java b/interop/org/apache/ws/axis/oasis/Scenario3.java
new file mode 100644
index 0000000..5e98a3d
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario3.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario3
+ */
+public class Scenario3 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping3";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing3(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 3 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+//        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+//                System.out.println("\nLoop #" + i);
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario4.java b/interop/org/apache/ws/axis/oasis/Scenario4.java
new file mode 100644
index 0000000..caa262a
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario4.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario4
+ */
+public class Scenario4 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping4";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing4(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 4 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario5.java b/interop/org/apache/ws/axis/oasis/Scenario5.java
new file mode 100644
index 0000000..619dfea
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario5.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+import org.apache.ws.axis.oasis.ping.TicketType;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario5
+ */
+public class Scenario5 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping5";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing5(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 5 - text");
+        TicketType type = 
+                new TicketType("WSS4J - Scenario 5 - TicketType");
+        
+        port.ping(type, text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(type, text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario6.java b/interop/org/apache/ws/axis/oasis/Scenario6.java
new file mode 100644
index 0000000..f620b6e
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario6.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario6
+ */
+public class Scenario6 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping6";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing6(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 6 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Scenario7.java b/interop/org/apache/ws/axis/oasis/Scenario7.java
new file mode 100644
index 0000000..1f875b7
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Scenario7.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Scenario6
+ */
+public class Scenario7 {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:9080/axis/services/Ping7";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing7(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario 7 text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/Tester.java b/interop/org/apache/ws/axis/oasis/Tester.java
new file mode 100644
index 0000000..b7a36fe
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/Tester.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.oasis;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+
+import javax.xml.rpc.holders.StringHolder;
+
+/**
+ * Class Tester
+ */
+public class Tester {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:8081/axis/services/SecHttp";
+
+    /**
+     * Method main
+     * 
+     * @param args 
+     * @throws Exception 
+     */
+    public static void main(String[] args) throws Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        /*
+         *     Start to prepare service call. Once this is done, several
+         *     calls can be made on the port (see below)
+         *
+         *     Fist: get the service locator. This implements the functionality
+         *     to get a client stub (aka port).
+         */
+        PingServiceLocator service = new PingServiceLocator();
+
+        /*
+         *     this is a JAX-RPC compliant call. It uses a preconfigured
+         *     endpoint address (usually contained in the WSDL). Note the
+         *     cast.
+         *    
+         * SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+         *     Here we use an Axis specific call that allows to override the
+         *     port address (service endpoint address) with an own URL. Comes
+         *     in handy for testing.
+         */
+        java.net.URL endpoint;
+
+        try {
+            endpoint = new java.net.URL(opts.getURL());
+        } catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+
+        PingPort port = (PingPort) service.getPing1(endpoint);
+
+        /*
+         *     At this point all preparations are done. Using the port we can
+         *     now perform as many calls as necessary.
+         */
+
+        // perform call
+        StringHolder text =
+                new StringHolder("WSS4J - Tester text");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+        System.out.println(text.value);
+
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+
+            for (int i = 0; i < 20; i++) {
+                port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J"), text);
+            }
+
+            long endTime = System.currentTimeMillis();
+
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
diff --git a/interop/org/apache/ws/axis/oasis/ping/PingBindingImpl.java b/interop/org/apache/ws/axis/oasis/ping/PingBindingImpl.java
new file mode 100644
index 0000000..31d1374
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/ping/PingBindingImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * PingBindingImpl.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.oasis.ping;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.handler.WSHandlerResult;
+
+import javax.xml.rpc.holders.StringHolder;
+import java.util.Vector;
+
+public class PingBindingImpl
+    implements org.apache.ws.axis.oasis.ping.PingPort {
+    public void ping(
+            org.apache.ws.axis.oasis.ping.TicketType pingTicket, 
+        StringHolder text)
+        throws java.rmi.RemoteException {
+        MessageContext msgContext = MessageContext.getCurrentContext();
+        Message reqMsg = msgContext.getRequestMessage();
+
+        Vector results = null;
+        if ((results =
+            (Vector) msgContext.getProperty(WSHandlerConstants.RECV_RESULTS))
+            == null) {
+            System.out.println("No security results!!");
+        }
+        System.out.println("Number of results: " + results.size());
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                (WSHandlerResult) results.get(i);
+            Vector wsSecEngineResults = rResult.getResults();
+
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                    (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                if (wser.getAction() != WSConstants.ENCR && wser.getPrincipal() != null) {
+                    System.out.println(wser.getPrincipal().getName());
+                }
+            }
+        }
+    }
+
+}
diff --git a/interop/org/apache/ws/axis/oasis/ping/deploy.wsdd b/interop/org/apache/ws/axis/oasis/ping/deploy.wsdd
new file mode 100644
index 0000000..0771acc
--- /dev/null
+++ b/interop/org/apache/ws/axis/oasis/ping/deploy.wsdd
@@ -0,0 +1,420 @@
+<!-- Use this file to deploy some handlers/chains and services      -->
+<!-- Two ways to do this:                                           -->
+<!--   java org.apache.axis.client.AdminClient deploy.wsdd          -->
+<!--      after the axis server is running                          -->
+<!-- or                                                             -->
+<!--   java org.apache.axis.utils.Admin client|server deploy.wsdd   -->
+<!--      from the same directory that the Axis engine runs         -->
+
+<deployment
+    xmlns="http://xml.apache.org/axis/wsdd/"
+    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+
+ <globalConfiguration>
+   <parameter name="disablePrettyXML" value="true"/>
+   <parameter name="enableNamespacePrefixOptimization" value="true"/>
+ </globalConfiguration>
+
+  <!-- Services from PingService WSDL service -->
+
+  <service name="Ping1" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping1"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="UsernameToken"/>
+   </handler>
+  </requestFlow>
+  </service>
+
+  <service name="Ping2" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping2"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="UsernameToken Encrypt"/>
+    <parameter name="decryptionPropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  </service>
+
+  <service name="Ping2a" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping2"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="UsernameTokenSignature UsernameToken Encrypt Timestamp"/>
+    <parameter name="decryptionPropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  </service>
+
+  <service name="Ping3" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping3"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <!-- Use the Server's cert/key to sign the response -->
+    <parameter name="user" value="bob"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <!-- Use the Client's cert/key to encrypt the response -->
+    <parameter name="encryptionUser" value="alice" />
+   </handler>
+  </responseFlow>
+  </service>
+    
+  <service name="Ping4" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping4"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <!-- Use the Server's cert/key to sign the response -->
+    <parameter name="user" value="bob"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="EmbeddedKeyName" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <parameter name="EmbeddedKeyCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1" />
+    <parameter name="EmbeddedKeyName" value="SessionKey" />
+   </handler>
+  </responseFlow>
+  </service>
+
+  <service name="Ping5" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping5"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Signature Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  </service>
+
+  <service name="Ping6" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping6"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Encrypt Signature Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Encrypt Signature Timestamp"/>
+    <!-- Use the Server's cert/key to sign the response -->
+    <parameter name="user" value="bob"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />    
+    <!-- Use the Client's cert/key to encrypt the response -->
+    <parameter name="encryptionUser" value="alice" />
+   </handler>
+  </responseFlow>
+  </service>
+
+  <service name="Ping7" provider="java:RPC" style="wrapped" use="literal">
+      <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+      <parameter name="wsdlServiceElement" value="PingService"/>
+      <parameter name="wsdlServicePort" value="Ping7"/>
+      <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+      <parameter name="wsdlPortType" value="PingPort"/>
+      <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping" >
+        <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+        <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+      </operation>
+      <parameter name="allowedMethods" value="ping"/>
+
+      <typeMapping
+        xmlns:ns="http://xmlsoap.org/Ping"
+        qname="ns:ticketType"
+        type="java:org.apache.ws.axis.oasis.ping.TicketType"
+        serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+        deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+        encodingStyle=""
+      />
+
+  <requestFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="decryptionPropFile" value="wsstest.properties" />
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="action" value="Signature Encrypt Timestamp"/>
+    <!-- Use the Server's cert/key to sign the response -->
+    <parameter name="user" value="bob"/>
+    <parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+    <parameter name="signatureKeyIdentifier" value="SKIKeyIdentifier" />
+    <parameter name="signaturePropFile" value="wsstest.properties" />
+    <parameter name="encryptionPropFile" value="wsstest.properties" />
+    <parameter name="encryptionKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />   
+    <!-- Use the Client's cert/key to encrypt the response -->    
+    <parameter name="encryptionUser" value="alice" />
+   </handler>
+  </responseFlow>
+      
+  </service>
+    
+    <service name="STPing1" provider="java:RPC" style="wrapped" use="literal">
+        <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+        <parameter name="wsdlServiceElement" value="PingService"/>
+        <parameter name="wsdlServicePort" value="STPing1"/>
+        <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+        <parameter name="wsdlPortType" value="PingPort"/>
+        <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping">
+            <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+            <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+        </operation>
+        <parameter name="allowedMethods" value="ping"/>
+        <typeMapping
+            xmlns:ns="http://xmlsoap.org/Ping"
+            qname="ns:ticketType"
+            type="java:org.apache.ws.axis.oasis.ping.TicketType"
+            serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+            deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+            encodingStyle=""
+            />
+        <requestFlow>
+            <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+                <parameter name="action" value="Timestamp SAMLTokenUnsigned"/>
+            </handler>
+        </requestFlow>
+    </service>
+    
+    <service name="STPing3" provider="java:RPC" style="wrapped" use="literal">
+        <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+        <parameter name="wsdlServiceElement" value="PingService"/>
+        <parameter name="wsdlServicePort" value="STPing1"/>
+        <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+        <parameter name="wsdlPortType" value="PingPort"/>
+        <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping">
+            <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+            <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+        </operation>
+        <parameter name="allowedMethods" value="ping"/>
+        <typeMapping
+            xmlns:ns="http://xmlsoap.org/Ping"
+            qname="ns:ticketType"
+            type="java:org.apache.ws.axis.oasis.ping.TicketType"
+            serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+            deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+            encodingStyle=""
+            />
+		<!--
+		 ATTENTION: depending on the SAML token type (here "sender vouches") _and_
+		 the keyIdentfier specified by the sender be sure to set the correct
+		 crypto.properties
+		 
+		 action: if the sender specifies "SAMLTokenSigned" then DoAllSender
+		 performs two actions: inserting a SAML Token (unsigned) _and_ an
+		 associated Signature. Thus, at the receiver's side, we need to
+		 define both :-)
+		 -->
+
+        <requestFlow>
+            <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+                <parameter name="action" value="Timestamp Signature SAMLTokenUnsigned"/>
+                <parameter name="signaturePropFile" value="crypto.properties" />
+                
+            </handler>
+        </requestFlow>
+    </service>
+
+    <service name="STPing4" provider="java:RPC" style="wrapped" use="literal">
+        <parameter name="wsdlTargetNamespace" value="http://xmlsoap.org/Ping"/>
+        <parameter name="wsdlServiceElement" value="PingService"/>
+        <parameter name="wsdlServicePort" value="STPing1"/>
+        <parameter name="className" value="org.apache.ws.axis.oasis.ping.PingBindingImpl"/>
+        <parameter name="wsdlPortType" value="PingPort"/>
+        <operation name="ping" qname="operNS:Ping" xmlns:operNS="http://xmlsoap.org/Ping">
+            <parameter qname="pns:ticket" xmlns:pns="http://xmlsoap.org/Ping" type="tns:ticketType" xmlns:tns="http://xmlsoap.org/Ping"/>
+            <parameter qname="pns:text" xmlns:pns="http://xmlsoap.org/Ping" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" mode="INOUT"/>
+        </operation>
+        <parameter name="allowedMethods" value="ping"/>
+        <typeMapping
+            xmlns:ns="http://xmlsoap.org/Ping"
+            qname="ns:ticketType"
+            type="java:org.apache.ws.axis.oasis.ping.TicketType"
+            serializer="org.apache.axis.encoding.ser.SimpleSerializerFactory"
+            deserializer="org.apache.axis.encoding.ser.SimpleDeserializerFactory"
+            encodingStyle=""
+            />
+		<!--
+		 ATTENTION: depending on the SAML token type (here "key holder") _and_
+		 the keyIdentfier specified by the sender be sure to set the correct
+		 crypto.properties
+		 
+		 action: if the sender specifies "SAMLTokenSigned" then DoAllSender
+		 performs two actions: inserting a SAML Token (unsigned) _and_ an
+		 associated Signature. Thus, at the receiver's side, we need to
+		 define both :-)
+		 -->
+        <requestFlow>
+            <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+                <parameter name="action" value="Timestamp Signature SAMLTokenUnsigned"/>
+			    <parameter name="signaturePropFile" value="crypto.properties" />
+                
+            </handler>
+        </requestFlow>
+    </service>
+
+
+</deployment>
\ No newline at end of file
diff --git a/interop/ping.wsdl b/interop/ping.wsdl
new file mode 100644
index 0000000..c470868
--- /dev/null
+++ b/interop/ping.wsdl
@@ -0,0 +1,99 @@
+<definitions xmlns:s1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
+             xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:s="http://www.w3.org/2001/XMLSchema"
+             xmlns:tns="http://xmlsoap.org/Ping"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
+             xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+             targetNamespace="http://xmlsoap.org/Ping"
+             xmlns="http://schemas.xmlsoap.org/wsdl/">
+    <types>
+        <s:schema elementFormDefault="qualified" targetNamespace="http://xmlsoap.org/Ping">
+            <s:import namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
+            <s:element name="Ping" nillable="true" type="tns:ping"/>
+            <s:complexType name="ping">
+                <s:sequence>
+                    <s:element minOccurs="0" maxOccurs="1" name="ticket" type="tns:ticketType"/>
+                    <s:element minOccurs="1" maxOccurs="1" name="text" nillable="true" type="s:string"/>
+                </s:sequence>
+            </s:complexType>
+            <s:complexType name="ticketType">
+                <s:simpleContent>
+                    <s:extension base="s:string">
+                        <s:attribute ref="s1:Id"/>
+                    </s:extension>
+                </s:simpleContent>
+            </s:complexType>
+            <s:element name="PingResponse" nillable="true" type="tns:pingResponse"/>
+            <s:complexType name="pingResponse">
+                <s:sequence>
+                    <s:element minOccurs="1" maxOccurs="1" name="text" nillable="true" type="s:string"/>
+                </s:sequence>
+            </s:complexType>
+        </s:schema>
+        <s:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+            <s:attribute name="Id" type="s:string"/>
+        </s:schema>
+    </types>
+    <message name="PingRequest">
+        <part name="ping" element="tns:Ping"/>
+    </message>
+    <message name="PingResponse">
+        <part name="pingResponse" element="tns:PingResponse"/>
+    </message>
+    <portType name="PingPort">
+        <operation name="Ping">
+            <input message="tns:PingRequest"/>
+            <output message="tns:PingResponse"/>
+        </operation>
+    </portType>
+    <binding name="PingBinding" type="tns:PingPort">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <operation name="Ping">
+            <soap:operation soapAction="Ping" style="document"/>
+            <input>
+                <soap:body use="literal"/>
+            </input>
+            <output>
+                <soap:body use="literal"/>
+            </output>
+        </operation>
+    </binding>
+    <service name="PingService">
+        <port name="Ping1" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping1"/>
+        </port>
+        <port name="Ping2" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping2"/>
+        </port>
+        <port name="Ping2a" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping2a"/>
+        </port>
+        <port name="Ping3" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping3"/>
+        </port>
+        <port name="Ping4" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping4"/>
+        </port>
+        <port name="Ping5" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping5"/>
+        </port>
+        <port name="Ping6" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping6"/>
+        </port>
+        <port name="Ping7" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/Ping7"/>
+        </port>
+        <port name="STPing1" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/STPing1"/>
+        </port>
+        <port name="STPing3" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/STPing3"/>
+        </port>
+        <port name="STPing4" binding="tns:PingBinding">
+            <soap:address location="http://localhost:9080/pingservice/STPing4"/>
+        </port>
+        
+    </service>
+</definitions>
\ No newline at end of file
diff --git a/interop/utility.xsd b/interop/utility.xsd
new file mode 100644
index 0000000..ec531e8
--- /dev/null
+++ b/interop/utility.xsd
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+Copyright © OASIS Open 2002. All Rights Reserved.
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+This document and the information contained herein is provided on an “AS IS” basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+-->
+<xsd:schema targetNamespace="http://schemas.xmlsoap.org/ws/2003/06/utility" xmlns="http://schemas.xmlsoap.org/ws/2003/06/utility" xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.1">
+	<!-- // Fault Codes /////////////////////////////////////////// -->
+	<xsd:simpleType name="tTimestampFault">
+		<xsd:annotation>
+			<xsd:documentation>
+This type defines the fault code value for Timestamp message expiration.
+          </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:QName">
+			<xsd:enumeration value="wsu:MessageExpired"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+	<!-- // Global attributes //////////////////////////////////// -->
+	<xsd:attribute name="Id" type="xsd:ID">
+		<xsd:annotation>
+			<xsd:documentation>
+This global attribute supports annotating arbitrary elements with an ID.
+          </xsd:documentation>
+		</xsd:annotation>
+	</xsd:attribute>
+	<xsd:attributeGroup name="commonAtts">
+		<xsd:annotation>
+			<xsd:documentation>
+Convenience attribute group used to simplify this schema.
+          </xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute ref="wsu:Id" use="optional"/>
+		<xsd:anyAttribute namespace="##other" processContents="lax"/>
+	</xsd:attributeGroup>
+	<!-- // Utility types //////////////////////////////////////// -->
+	<xsd:complexType name="AttributedDateTime">
+		<xsd:annotation>
+			<xsd:documentation>
+This type is for elements whose [children] is a psuedo-dateTime and can have arbitrary attributes. 
+      </xsd:documentation>
+		</xsd:annotation>
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:attribute name="ValueType" type="xsd:QName">
+					<xsd:annotation>
+						<xsd:documentation>
+This attribute indicates the actual schema type of the element [children]. 
+If the ValueType attribute is present, conforming processors must process the string value of [children] as if it were affiliated with the type indicated by this attribute.
+If the ValueType attribute is absent, the implied value of this attribute is xsd:dateTime.
+            </xsd:documentation>
+					</xsd:annotation>
+				</xsd:attribute>
+				<xsd:attributeGroup ref="wsu:commonAtts"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	<xsd:complexType name="AttributedURI">
+		<xsd:annotation>
+			<xsd:documentation>
+This type is for elements whose [children] is an anyURI and can have arbitrary attributes.
+      </xsd:documentation>
+		</xsd:annotation>
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:anyURI">
+				<xsd:attributeGroup ref="wsu:commonAtts"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	<!-- // Timestamp header components /////////////////////////// -->
+	<xsd:complexType name="TimestampType">
+		<xsd:annotation>
+			<xsd:documentation>
+This complex type ties together the timestamp related elements into a composite type.
+            </xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element ref="wsu:Created" minOccurs="0"/>
+			<xsd:element ref="wsu:Expires" minOccurs="0"/>
+			<xsd:choice minOccurs="0" maxOccurs="unbounded">
+				<xsd:any namespace="##other" processContents="lax"/>
+			</xsd:choice>
+		</xsd:sequence>
+		<xsd:attributeGroup ref="wsu:commonAtts"/>
+	</xsd:complexType>
+	<xsd:element name="Timestamp" type="wsu:TimestampType">
+		<xsd:annotation>
+			<xsd:documentation>
+This element allows Timestamps to be applied anywhere element wildcards are present,
+including as a SOAP header.
+            </xsd:documentation>
+		</xsd:annotation>
+	</xsd:element>
+	<!-- global element decls to allow individual elements to appear anywhere -->
+	<xsd:element name="Expires" type="wsu:AttributedDateTime">
+		<xsd:annotation>
+			<xsd:documentation>
+This element allows an expiration time to be applied anywhere element wildcards are present.
+            </xsd:documentation>
+		</xsd:annotation>
+	</xsd:element>
+	<xsd:element name="Created" type="wsu:AttributedDateTime">
+		<xsd:annotation>
+			<xsd:documentation>
+This element allows a creation time to be applied anywhere element wildcards are present.
+            </xsd:documentation>
+		</xsd:annotation>
+	</xsd:element>
+</xsd:schema>
diff --git a/interop/wsstest.properties b/interop/wsstest.properties
new file mode 100644
index 0000000..2dfd990
--- /dev/null
+++ b/interop/wsstest.properties
@@ -0,0 +1,5 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=password
+org.apache.ws.security.crypto.merlin.file=interop/interop2.jks
+
diff --git a/interop/wsstest1.pfx b/interop/wsstest1.pfx
new file mode 100644
index 0000000..f7c781a
--- /dev/null
+++ b/interop/wsstest1.pfx
Binary files differ
diff --git a/interop/wsstest2.pfx b/interop/wsstest2.pfx
new file mode 100644
index 0000000..1ca1eb3
--- /dev/null
+++ b/interop/wsstest2.pfx
Binary files differ
diff --git a/keys/.keystore b/keys/.keystore
new file mode 100644
index 0000000..55f59c8
--- /dev/null
+++ b/keys/.keystore
Binary files differ
diff --git a/keys/BCMain.java b/keys/BCMain.java
new file mode 100644
index 0000000..9699778
--- /dev/null
+++ b/keys/BCMain.java
@@ -0,0 +1,296 @@
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.util.Enumeration;
+
+public class BCMain {
+    public static void main(String[] args) {
+        //==============================
+        // Setup stuff
+        //==============================
+
+        //Input FileName, Alias and Password
+        String jksFileName = ".keystore";
+        String jksAlias = "dims";
+        char[] jksPassword = "security".toCharArray();
+
+        //Output FileName, Alias and Password
+        String pkcs12FileName = "keystore.p12";
+        String pkcs12Alias = "dims";
+        char[] pkcs12Password = "security".toCharArray();
+
+        //Plug the Provider into the JCA/JCE
+        Security.addProvider(new BouncyCastleProvider());
+
+
+
+        //================================
+        // JKS Stuff
+        //================================
+
+        InputStream jksInputStream = null;
+        try {
+            jksInputStream = new FileInputStream(jksFileName);
+            System.out.println("Establish JKS InputStream to " +
+                    jksFileName);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        KeyStore jksKeyStore = null;
+        try {
+            jksKeyStore = KeyStore.getInstance("JKS", "SUN");
+            System.out.println("Create JKS KeyStore Object.");
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchProviderException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Load the keystore
+        try {
+            jksKeyStore.load(jksInputStream, jksPassword);
+            System.out.println("Load JKS KeyStore.");
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (CertificateException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Fetch all aliases from the keystore.
+        Enumeration aliases = null;
+        try {
+            aliases = jksKeyStore.aliases();
+            System.out.println("Got KeyStore aliases.");
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Shows all aliases from the keystore, only for info
+        while (aliases.hasMoreElements()) {
+            System.out.println("Has alias: " + aliases.nextElement());
+        }
+
+
+
+        //Get PrivateKey
+        RSAPrivateCrtKey jksPrivateCrtKey = null;
+        try {
+            jksPrivateCrtKey =
+                    (RSAPrivateCrtKey) jksKeyStore.getKey(jksAlias, jksPassword);
+            System.out.println("Get PKCS#12 RSAPrivateCrtKey(" + jksPrivateCrtKey +
+                    "): [Bit-Length: " + jksPrivateCrtKey.getModulus().bitLength() +
+                    ", Modulus: " + jksPrivateCrtKey.getModulus() +
+                    ", PublicExponent: " + jksPrivateCrtKey.getPublicExponent() +
+                    ", PrivateExponent: " + jksPrivateCrtKey.getPrivateExponent() +
+                    ", Prime-P: " + jksPrivateCrtKey.getPrimeP() +
+                    ", Prime-Q: " + jksPrivateCrtKey.getPrimeQ() +
+                    ", Prime-Exponent-P: " + jksPrivateCrtKey.getPrimeExponentP() +
+                    ", Prime-Exponent-Q: " + jksPrivateCrtKey.getPrimeExponentQ() +
+                    ", CRT-Coefficient: " + jksPrivateCrtKey.getCrtCoefficient()
+            );
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (UnrecoverableKeyException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Get Certificate
+        Certificate jksCert = null;
+        try {
+            jksCert = jksKeyStore.getCertificate(jksAlias);
+            System.out.println("Get Certificate from PKCS#12: " + jksCert);
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Get Certificate Chain
+        Certificate[] jksCerts = null;
+        try {
+            jksCerts = jksKeyStore.getCertificateChain(jksAlias);
+            System.out.println("Get Certificate Chain from JKS, with " +
+                    jksCerts.length + " certs.");
+            for (int i = 0; i < jksCerts.length; i++) {
+                System.out.println("Certificate " + (i + 1) +
+                        " from JKS in the chain: " + jksCerts[i]);
+            }
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //=====================================
+        // PKCS#12 stuff
+        //=====================================
+
+        KeyStore pkcs12KeyStore = null;
+        try {
+            pkcs12KeyStore = KeyStore.getInstance("PKCS12", "BC");
+            System.out.println("Create PKCS#12 KeyStore Object.");
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchProviderException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        try {
+            pkcs12KeyStore.load(null, pkcs12Password);
+            System.out.println(
+                    "Load a new fresh PKCS#12 KeyStore from scratch.");
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (CertificateException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        try {
+            pkcs12KeyStore.setKeyEntry(pkcs12Alias, jksPrivateCrtKey,
+                    pkcs12Password, jksCerts);
+            System.out.println("Add the RSA Private Crt Key and the " +
+                    "Certificate Chain to the PKCS#12 KeyStore.");
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        OutputStream pkcs12OutputStream = null;
+        try {
+            pkcs12OutputStream = new FileOutputStream(pkcs12FileName);
+            System.out.println(
+                    "Establish PKCS#12 OutputStream to " + pkcs12FileName);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        try {
+            pkcs12KeyStore.store(pkcs12OutputStream, pkcs12Password);
+            pkcs12OutputStream.close();
+            System.out.println("Store PKCS#12 KeyStore: " + pkcs12FileName);
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (CertificateException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //=====================================
+        // Reread the pkcs12KeyStore
+        //=====================================
+
+        InputStream pkcs12InputStream = null;
+        try {
+            pkcs12InputStream = new FileInputStream(pkcs12FileName);
+            System.out.println(
+                    "Establish PKCS#12 InputStream to " + pkcs12FileName);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        try {
+            pkcs12KeyStore.load(pkcs12InputStream, pkcs12Password);
+            System.out.println("Re-read the PKCS#12 KeyStore.");
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (CertificateException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Get PrivateKey
+        RSAPrivateCrtKey pkcs12PrivateCrtKey = null;
+        try {
+            pkcs12PrivateCrtKey =
+                    (RSAPrivateCrtKey) pkcs12KeyStore.getKey(pkcs12Alias, pkcs12Password);
+            System.out.println(
+                    "Get PKCS#12 RSAPrivateCrtKey(" + pkcs12PrivateCrtKey +
+                    "): [Bit-Length: " + pkcs12PrivateCrtKey.getModulus().bitLength() +
+                    ", Modulus: " + pkcs12PrivateCrtKey.getModulus() +
+                    ", PublicExponent: " + pkcs12PrivateCrtKey.getPublicExponent() +
+                    ", PrivateExponent: " + pkcs12PrivateCrtKey.getPrivateExponent() +
+                    ", Prime-P: " + pkcs12PrivateCrtKey.getPrimeP() +
+                    ", Prime-Q: " + pkcs12PrivateCrtKey.getPrimeQ() +
+                    ", Prime-Exponent-P: " + pkcs12PrivateCrtKey.getPrimeExponentP() +
+                    ", Prime-Exponent-Q: " + pkcs12PrivateCrtKey.getPrimeExponentQ() +
+                    ", CRT-Coefficient: " + pkcs12PrivateCrtKey.getCrtCoefficient()
+            );
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            System.exit(1);
+        } catch (UnrecoverableKeyException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Get Certificate
+        Certificate pkcs12Cert = null;
+        try {
+            pkcs12Cert = pkcs12KeyStore.getCertificate(pkcs12Alias);
+            System.out.println("Get Certificate from PKCS#12: " + pkcs12Cert);
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        //Get Certificate Chain
+        Certificate[] pkcs12Certs = null;
+        try {
+            pkcs12Certs = pkcs12KeyStore.getCertificateChain(pkcs12Alias);
+            System.out.println("Get Certificate Chain from PKCS#12, with " +
+                    pkcs12Certs.length + " certs.");
+            for (int i = 0; i < pkcs12Certs.length; i++) {
+                System.out.println("Certificate " + (i + 1) +
+                        " from PKCS#12 in the chain: " + pkcs12Certs[i]);
+            }
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+}
diff --git a/keys/CA.pem b/keys/CA.pem
new file mode 100644
index 0000000..1c490ed
--- /dev/null
+++ b/keys/CA.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDFjCCAn+gAwIBAgIJAOZ4AGEHvNpGMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNV
+BAYTAkRFMQ8wDQYDVQQIEwZCYXllcm4xDzANBgNVBAcTBk11bmljaDENMAsGA1UE
+ChMESG9tZTEVMBMGA1UECxMMQXBhY2hlIFdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIw
+HhcNMDYwMzEwMTY1NjM4WhcNMDYwNDA5MTY1NjM4WjBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMIGfMA0GCSqG
+SIb3DQEBAQUAA4GNADCBiQKBgQDRe6cFThsaLpiqCcBGF7cB43U4ubwxex7oL+oI
+QNU9oasq7M+lxRLqwjDoiKq1/IgXcKmuPKxrUQy8TaTE9j6YevHYJ5akfjbuRS0f
+coySrsY6lLcExGisbdhgFhp/Y75ECiSsnFUP0W5MR2GSHmmC9ySiVrRWBcfcopEL
+6PTVBQIDAQABo4HLMIHIMB0GA1UdDgQWBBTZlSpKP3bQh6ix8P+EuMB6EbkxdjCB
+mAYDVR0jBIGQMIGNgBTZlSpKP3bQh6ix8P+EuMB6EbkxdqFqpGgwZjELMAkGA1UE
+BhMCREUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ0wCwYDVQQK
+EwRIb21lMRUwEwYDVQQLEwxBcGFjaGUgV1NTNEoxDzANBgNVBAMTBldlcm5lcoIJ
+AOZ4AGEHvNpGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAbewcpji0
+jJGT/ASDmHaLIrTQ4m7ScOFRasfUrvXkO/rgJi47uyCPMqlSdXhchcmUhDaY3GK7
+D9Dqr/+zYoKkZWKGScOm4BfSD4mez1tDgnF/BTd2HbfQbj9lHognAp7lGqgpsX1/
+6JSRES/7ZbbqTtuSpyJ6BtdiHSRHnT3l0uw=
+-----END CERTIFICATE-----
diff --git a/keys/CAKey.pem b/keys/CAKey.pem
new file mode 100644
index 0000000..792fd4e
--- /dev/null
+++ b/keys/CAKey.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,EC101A253DEA1D77
+
+Igs4XK7ODgaXHusnchmM/kLDi1Jkwqo0DNohkVfqt8BHCoyQ6dhrhoJTOzbay/Ko
+C6Un00XUUnOAUSX98Z6TZPiAmgBKG5JTE09xddkWb+GpDFge90QtKRupdF1DPvZC
+h+JbMXm6SDQbD9tqhPmj0ZiujkaTWq4S2R+/jzl0+O+tX/tesnrHoc1sy4hwZtFq
+PsgewoAWbKbXEhObaDDudfF+p3h2xKCaJd3Cfbw24rLWLuq3NXjj5184GU1zSQdS
+pigyK0cbA7EtuAWaG3H/6Um3fthQG+R4DW/IShi9jVnVBTe4R9XhJ8reUEeqgi5o
+AEhImkNd4Hxg0FXhI2GDdNrP+8pK8WJOSZb6pJoT35oBjYQYy5/AI93jyCJmX8i2
+OGVDUQMmo/wPGJnI39rFR/bVsBms5Z+TOu7Vd7MP3hJqmWmPBkuWAWRGy3Iphw4n
+fRM6XsnPz43OPsYpLh5dDZ3c4csWCmtj1mXCYhTUg1FH5GLMKW21bWHLU4moPIEH
+t9EGCDntVioPAFRTQCU0HQHXI2waoGcWfjQs3lXtdyAVldFf27TxSPoYq0rkHVBw
+bFgquOMzFVdHJYYt8F4aWd3MvDy5c10ax+22b1ziyj87GsJRnBFuMM5PxbT0bNLA
+a7WMIL9TG5Np9ff4sRY18Q+m/z92Yko4zRyij1h+Pj8pNBmw5hRCJf/IvIfUrGwM
+pvrDZMFmMAwYvZDex+Vi6xIi3nXopt6LT2iUY849qKPZQjhSLKsBTDLYPRSgcZ2B
+3ytblw1OgTa1A9NbYI17WQUjtl91p9HZVj+ZR1f1ScHUn3LI17fMvw==
+-----END RSA PRIVATE KEY-----
diff --git a/keys/ca.config b/keys/ca.config
new file mode 100644
index 0000000..b4abb6b
--- /dev/null
+++ b/keys/ca.config
@@ -0,0 +1,74 @@
+#

+# Beginning of file ca.config

+[ ca ]

+default_ca              = CA_own

+[ CA_own ]

+dir                     = .

+certs                   = $dir

+new_certs_dir           = $dir/ca.db.certs

+database                = $dir/ca.db.index

+serial                  = $dir/ca.db.serial

+RANDFILE                = $dir/ca.db.rand

+certificate             = $dir/CA.pem

+private_key             = $dir/CAKey.pem

+default_days            = 365

+default_crl_days        = 30

+default_md              = md5

+preserve                = no

+x509_extensions         = usr_cert

+policy                  = policy_match

+#

+[ usr_cert ]

+basicConstraints        = CA:FALSE

+nsComment               = "OpenSSL Generated Certificate"

+subjectKeyIdentifier    = hash

+authorityKeyIdentifier  = keyid,issuer:always

+[ req ]

+default_bits            = 1024

+distinguished_name      = req_distinguished_name

+x509_extensions         = v3_ca

+policy                  = policy_anything

+[ v3_req ]

+basicConstraints        = CA:FALSE

+keyUsage                = nonRepudiation, digitalSignature, keyEncipherment

+[ v3_ca ]

+subjectKeyIdentifier    = hash

+authorityKeyIdentifier  = keyid:always,issuer:always

+basicConstraints        = CA:true

+#

+# For the CA policy

+#

+[ policy_match ]

+countryName             = match

+stateOrProvinceName     = match

+organizationName        = match

+organizationalUnitName  = optional

+commonName              = supplied

+emailAddress            = optional

+#

+[ policy_anything ]

+countryName             = optional

+stateOrProvinceName     = optional

+localityName            = optional

+organizationName        = optional

+organizationalUnitName  = optional

+commonName              = supplied

+emailAddress            = optional

+#

+[ req_distinguished_name ]

+countryName             = Country Name (2 letter code)

+countryName_default     = DE

+CountryName_min         = 2

+CountryName_max         = 2

+stateOrProvinceName     = State or Province Name (full name)

+stateOrProvinceName_default = Bayern

+localityName            = Locality Name (e.g., city)

+localityName_default    = Munich

+0.organizationName      = Organization Name (e.g., company)

+0.organizationName_default = Home

+organizationalUnitName  = Organizational Unit Name (e.g., section)

+organizationalUnitName_default = Apache WSS4J

+commonName              = Common Name (e.g., your name or server name)

+commonName_max          = 64

+commonName_default		= Werner

+# end of file ca.config

diff --git a/keys/ca.crt b/keys/ca.crt
new file mode 100644
index 0000000..cc98749
--- /dev/null
+++ b/keys/ca.crt
Binary files differ
diff --git a/keys/ca.db.certs/01.pem b/keys/ca.db.certs/01.pem
new file mode 100644
index 0000000..fb2cd2d
--- /dev/null
+++ b/keys/ca.db.certs/01.pem
@@ -0,0 +1,92 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Feb 29 10:51:17 2004 GMT
+            Not After : Feb 28 10:51:17 2005 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=werner
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:e2:aa:a5:25:3a:2e:7b:7f:88:1a:73:a1:d1:1a:
+                    2d:5f:a1:fa:2b:bf:0c:de:55:f2:88:34:21:6c:eb:
+                    71:5a:2c:ce:e4:d1:b4:e6:7b:87:f8:33:2b:83:4c:
+                    4a:05:d0:f5:6c:50:b7:4a:aa:57:44:7a:7a:6c:e7:
+                    37:d1:2c:8d:97:98:34:e1:6b:72:a3:e9:cb:69:02:
+                    57:e9:0d:5d:ab:e8:a2:47:1d:15:01:cf:3d:7b:a8:
+                    c3:23:ea:8e:85:c9:e8:74:60:64:a8:c1:07:16:b2:
+                    87:6b:5d:c9:f8:eb:65:23:3e:2d:33:8a:9a:8f:09:
+                    e0:12:45:8d:7f:fe:44:70:e1
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                55:B1:89:EB:BB:5E:9D:51:54:1C:50:AE:33:84:FC:22:E7:B6:4A:21
+            X509v3 Authority Key Identifier: 
+                keyid:D0:C2:5B:D0:A4:D4:EB:05:FD:7C:4C:0E:A7:1E:2F:A0:CA:68:4F:3A
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        4b:e7:2b:8f:1b:19:92:34:52:af:b5:97:61:33:53:88:c0:dc:
+        db:fd:1c:30:11:3b:38:ab:5a:b4:4f:e6:3a:91:67:ba:89:68:
+        1e:9b:40:70:bc:0c:1d:07:c2:a0:46:c9:fb:e1:4b:02:10:fc:
+        7d:98:81:d7:98:9f:4b:7c:24:4c:1d:b1:6a:45:ca:5b:e7:44:
+        a3:e6:e8:17:8d:1d:87:72:68:86:a4:c3:04:08:b0:ca:09:78:
+        c0:2c:f5:01:3e:6e:ef:eb:64:dc:6c:1e:ad:74:2a:15:87:ec:
+        c9:b5:c4:de:47:6a:27:f7:27:a2:eb:8d:ac:16:b9:c2:2b:16:
+        ce:b0
+-----BEGIN CERTIFICATE-----
+MIIERjCCA6+gAwIBAgIBATANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA0MDIy
+OTEwNTExN1oXDTA1MDIyODEwNTExN1owYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZ3ZXJuZXIwggG4MIIBLAYHKoZIzjgEATCCAR8C
+gYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F
+9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYV
+DwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKS
+uYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZ
+V4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFu
+o38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOB
+hQACgYEA4qqlJToue3+IGnOh0RotX6H6K78M3lXyiDQhbOtxWizO5NG05nuH+DMr
+g0xKBdD1bFC3SqpXRHp6bOc30SyNl5g04Wtyo+nLaQJX6Q1dq+iiRx0VAc89e6jD
+I+qOhcnodGBkqMEHFrKHa13J+OtlIz4tM4qajwngEkWNf/5EcOGjge4wgeswCQYD
+VR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlm
+aWNhdGUwHQYDVR0OBBYEFFWxieu7Xp1RVBxQrjOE/CLntkohMIGQBgNVHSMEgYgw
+gYWAFNDCW9Ck1OsF/XxMDqceL6DKaE86oWqkaDBmMQswCQYDVQQGEwJERTEPMA0G
+A1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUxFTAT
+BgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggEAMA0GCSqGSIb3
+DQEBBAUAA4GBAEvnK48bGZI0Uq+1l2EzU4jA3Nv9HDAROzirWrRP5jqRZ7qJaB6b
+QHC8DB0HwqBGyfvhSwIQ/H2YgdeYn0t8JEwdsWpFylvnRKPm6BeNHYdyaIakwwQI
+sMoJeMAs9QE+bu/rZNxsHq10KhWH7Mm1xN5Haif3J6LrjawWucIrFs6w
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/02.pem b/keys/ca.db.certs/02.pem
new file mode 100644
index 0000000..163081d
--- /dev/null
+++ b/keys/ca.db.certs/02.pem
@@ -0,0 +1,65 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Feb 29 12:00:29 2004 GMT
+            Not After : Feb 28 12:00:29 2005 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=wernerd
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:ad:ce:34:88:66:c7:13:0b:41:33:37:10:df:fd:
+                    87:2b:e0:3d:88:07:8d:84:7a:3c:51:1c:46:94:71:
+                    77:ad:e3:b1:4c:b3:30:0e:5d:b5:72:39:ee:89:2f:
+                    ab:bb:2f:08:2f:cd:de:a4:db:f7:4e:51:73:93:a2:
+                    21:e0:47:9f:8b:c2:58:05:c9:f4:60:8c:89:fa:d3:
+                    96:10:07:56:ce:de:06:63:e9:50:97:c1:83:3e:49:
+                    67:e5:82:eb:5f:ef:85:83:01:db:62:10:8d:27:20:
+                    3f:f3:03:40:6f:43:41:9e:e0:40:88:e5:bd:02:8f:
+                    a9:4a:10:58:83:7c:43:42:01
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                5E:61:46:E0:09:9A:44:80:9A:A4:B2:6F:04:00:24:F3:86:D6:16:8F
+            X509v3 Authority Key Identifier: 
+                keyid:D0:C2:5B:D0:A4:D4:EB:05:FD:7C:4C:0E:A7:1E:2F:A0:CA:68:4F:3A
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        7c:35:e4:e7:63:18:af:26:77:1c:5f:cc:e6:89:2b:ac:8d:a2:
+        f9:70:60:84:58:75:40:12:6e:b2:37:47:26:92:97:5e:f1:28:
+        06:35:1a:e2:48:6b:89:f3:f0:73:52:ad:77:ce:5a:01:c0:84:
+        cf:e4:3e:a4:ee:6e:ad:93:99:6b:ec:48:27:0e:f4:8c:c9:21:
+        12:76:43:ce:1c:af:c6:2e:1c:c3:eb:8e:22:29:58:50:d2:0d:
+        01:3e:19:df:0f:51:ea:88:37:9c:66:08:a1:df:71:73:11:20:
+        b7:02:19:38:e1:2f:53:d9:0b:1f:cb:62:6c:75:fa:42:10:24:
+        ff:4a
+-----BEGIN CERTIFICATE-----
+MIIDLTCCApagAwIBAgIBAjANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA0MDIy
+OTEyMDAyOVoXDTA1MDIyODEyMDAyOVowYjELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRAwDgYDVQQDEwd3ZXJuZXJkMIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQCtzjSIZscTC0EzNxDf/Ycr4D2IB42EejxRHEaUcXet47FMszAOXbVy
+Oe6JL6u7Lwgvzd6k2/dOUXOToiHgR5+LwlgFyfRgjIn605YQB1bO3gZj6VCXwYM+
+SWflgutf74WDAdtiEI0nID/zA0BvQ0Ge4ECI5b0Cj6lKEFiDfENCAQIDAQABo4Hu
+MIHrMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBReYUbgCZpEgJqksm8EACTzhtYWjzCBkAYD
+VR0jBIGIMIGFgBTQwlvQpNTrBf18TA6nHi+gymhPOqFqpGgwZjELMAkGA1UEBhMC
+REUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ0wCwYDVQQKEwRI
+b21lMRUwEwYDVQQLEwxBcGFjaGUgV1NTNEoxDzANBgNVBAMTBldlcm5lcoIBADAN
+BgkqhkiG9w0BAQQFAAOBgQB8NeTnYxivJnccX8zmiSusjaL5cGCEWHVAEm6yN0cm
+kpde8SgGNRriSGuJ8/BzUq13zloBwITP5D6k7m6tk5lr7EgnDvSMySESdkPOHK/G
+LhzD644iKVhQ0g0BPhnfD1HqiDecZgih33FzESC3Ahk44S9T2Qsfy2JsdfpCECT/
+Sg==
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/03.pem b/keys/ca.db.certs/03.pem
new file mode 100644
index 0000000..4e91469
--- /dev/null
+++ b/keys/ca.db.certs/03.pem
@@ -0,0 +1,92 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar  7 09:31:55 2004 GMT
+            Not After : Mar  7 09:31:55 2005 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=wernerdDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:b1:0d:e9:65:0f:68:ec:6c:f0:10:af:c5:1c:42:
+                    53:c0:43:0e:ee:66:5b:33:81:53:9f:87:a2:ef:05:
+                    0e:1f:38:85:33:7e:9d:4b:d9:ba:ea:21:f4:a2:60:
+                    9d:4b:b0:2a:d4:1f:5b:cb:9f:8d:d3:45:46:ef:07:
+                    4c:a1:b9:2d:86:df:f0:81:6f:2a:36:37:b5:c3:8f:
+                    4e:06:e7:87:06:1c:d6:aa:93:10:d8:d7:9b:57:9d:
+                    2b:08:05:f5:8c:1a:fb:d2:64:dd:f4:d3:32:0f:72:
+                    e6:90:03:da:a5:19:60:54:90:be:d8:d7:58:3b:1d:
+                    02:70:61:28:06:dd:c6:f3:45
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                0A:0E:82:F4:FE:57:60:75:CA:81:4F:78:27:3F:92:78:53:28:FF:88
+            X509v3 Authority Key Identifier: 
+                keyid:D0:C2:5B:D0:A4:D4:EB:05:FD:7C:4C:0E:A7:1E:2F:A0:CA:68:4F:3A
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        7a:23:9b:92:0b:95:82:da:5c:f7:e1:7b:1c:76:53:68:17:3d:
+        af:ec:22:94:29:a0:56:5b:4a:24:b9:cb:a5:0d:09:f2:60:cc:
+        1d:48:94:ee:b5:48:f4:16:1c:6a:8c:c4:82:66:e6:05:63:54:
+        65:e6:71:de:20:f4:28:06:73:ea:a8:8b:d5:8a:a1:d9:07:98:
+        a7:84:00:14:2d:aa:03:92:93:02:49:e5:4c:06:72:1e:cd:df:
+        98:21:f3:a3:fc:eb:86:5d:ea:ec:69:7b:99:a4:cb:d7:9c:e4:
+        da:72:fe:f2:0a:d3:d4:96:a1:20:f5:96:c5:d9:81:52:f4:2a:
+        26:31
+-----BEGIN CERTIFICATE-----
+MIIESjCCA7OgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA0MDMw
+NzA5MzE1NVoXDTA1MDMwNzA5MzE1NVowZTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRMwEQYDVQQDEwp3ZXJuZXJkRFNBMIIBuDCCASwGByqGSM44BAEw
+ggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2N
+WPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn
+xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
+C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H
+gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuz
+pnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7P
+SSoDgYUAAoGBALEN6WUPaOxs8BCvxRxCU8BDDu5mWzOBU5+Hou8FDh84hTN+nUvZ
+uuoh9KJgnUuwKtQfW8ufjdNFRu8HTKG5LYbf8IFvKjY3tcOPTgbnhwYc1qqTENjX
+m1edKwgF9Ywa+9Jk3fTTMg9y5pAD2qUZYFSQvtjXWDsdAnBhKAbdxvNFo4HuMIHr
+MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENl
+cnRpZmljYXRlMB0GA1UdDgQWBBQKDoL0/ldgdcqBT3gnP5J4Uyj/iDCBkAYDVR0j
+BIGIMIGFgBTQwlvQpNTrBf18TA6nHi+gymhPOqFqpGgwZjELMAkGA1UEBhMCREUx
+DzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ0wCwYDVQQKEwRIb21l
+MRUwEwYDVQQLEwxBcGFjaGUgV1NTNEoxDzANBgNVBAMTBldlcm5lcoIBADANBgkq
+hkiG9w0BAQQFAAOBgQB6I5uSC5WC2lz34XscdlNoFz2v7CKUKaBWW0okuculDQny
+YMwdSJTutUj0FhxqjMSCZuYFY1Rl5nHeIPQoBnPqqIvViqHZB5inhAAULaoDkpMC
+SeVMBnIezd+YIfOj/OuGXersaXuZpMvXnOTacv7yCtPUlqEg9ZbF2YFS9ComMQ==
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/06.pem b/keys/ca.db.certs/06.pem
new file mode 100644
index 0000000..8d3395a
--- /dev/null
+++ b/keys/ca.db.certs/06.pem
@@ -0,0 +1,64 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 6 (0x6)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 16:10:24 2006 GMT
+            Not After : Mar  9 16:10:24 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=werner
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1023 bit)
+                Modulus (1023 bit):
+                    72:0b:f1:36:fc:53:b6:20:5b:0e:1f:cc:2c:c6:3f:
+                    3e:f1:75:cc:25:4e:8f:ef:ec:b9:a0:70:95:ad:9a:
+                    6e:2c:03:1c:33:41:4b:4c:c3:22:5e:8d:96:4c:d9:
+                    cb:29:8b:0d:90:2d:7f:7c:1e:e6:27:dd:b1:cc:cc:
+                    b9:45:c0:99:56:4e:92:46:a1:92:ad:68:0c:7c:04:
+                    fd:50:1a:f0:08:9a:f3:56:4d:4b:55:cc:ac:95:cc:
+                    f2:4c:ce:40:e2:ad:63:fc:79:19:03:8f:cc:17:37:
+                    4f:4f:40:27:b2:84:83:41:3e:c9:7d:8a:17:44:6c:
+                    4c:38:09:63:a2:a0:08:3d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                E4:88:F1:D3:7B:E6:47:03:0F:95:C0:B6:91:1F:7F:15:6D:41:F1:84
+            X509v3 Authority Key Identifier: 
+                keyid:D0:C2:5B:D0:A4:D4:EB:05:FD:7C:4C:0E:A7:1E:2F:A0:CA:68:4F:3A
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        54:50:d9:76:0c:0f:40:f5:8d:f7:46:1a:6f:c9:f4:e3:f7:b8:
+        e0:b8:dc:fa:67:36:74:c2:92:84:f9:ba:8c:d2:b5:5b:cd:a9:
+        38:bf:57:2d:42:0f:78:df:9b:56:5b:0c:1f:a0:53:1f:fc:cf:
+        46:e8:04:1b:9c:87:23:23:79:20:ac:6a:af:a3:29:79:4a:ab:
+        46:a5:4f:12:93:97:9b:94:24:4d:e9:8e:78:25:34:6d:24:8b:
+        b7:c1:f0:0e:18:ef:88:51:44:91:30:0b:79:14:36:74:9f:c2:
+        b8:25:70:9e:5d:a9:60:da:7b:85:d9:cc:14:11:25:85:32:52:
+        ad:09
+-----BEGIN CERTIFICATE-----
+MIIDKzCCApSgAwIBAgIBBjANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE2MTAyNFoXDTA4MDMwOTE2MTAyNFowYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZ3ZXJuZXIwgZ4wDQYJKoZIhvcNAQEBBQADgYwA
+MIGIAoGAcgvxNvxTtiBbDh/MLMY/PvF1zCVOj+/suaBwla2abiwDHDNBS0zDIl6N
+lkzZyymLDZAtf3we5ifdsczMuUXAmVZOkkahkq1oDHwE/VAa8Aia81ZNS1XMrJXM
+8kzOQOKtY/x5GQOPzBc3T09AJ7KEg0E+yX2KF0RsTDgJY6KgCD0CAwEAAaOB7jCB
+6zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU5Ijx03vmRwMPlcC2kR9/FW1B8YQwgZAGA1Ud
+IwSBiDCBhYAU0MJb0KTU6wX9fEwOpx4voMpoTzqhaqRoMGYxCzAJBgNVBAYTAkRF
+MQ8wDQYDVQQIEwZCYXllcm4xDzANBgNVBAcTBk11bmljaDENMAsGA1UEChMESG9t
+ZTEVMBMGA1UECxMMQXBhY2hlIFdTUzRKMQ8wDQYDVQQDEwZXZXJuZXKCAQAwDQYJ
+KoZIhvcNAQEEBQADgYEAVFDZdgwPQPWN90Yab8n04/e44Ljc+mc2dMKShPm6jNK1
+W82pOL9XLUIPeN+bVlsMH6BTH/zPRugEG5yHIyN5IKxqr6MpeUqrRqVPEpOXm5Qk
+TemOeCU0bSSLt8HwDhjviFFEkTALeRQ2dJ/CuCVwnl2pYNp7hdnMFBElhTJSrQk=
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/07.pem b/keys/ca.db.certs/07.pem
new file mode 100644
index 0000000..a7079af
--- /dev/null
+++ b/keys/ca.db.certs/07.pem
@@ -0,0 +1,92 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 7 (0x7)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 16:10:37 2006 GMT
+            Not After : Mar  9 16:10:37 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=wernerDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:f1:9d:7d:ba:7c:8e:bb:2d:d4:ef:06:e8:9d:8f:
+                    55:d2:54:d5:fd:31:0a:2d:e7:a1:10:b8:cc:a0:3f:
+                    60:5a:07:04:4d:2c:e2:14:81:a6:a7:48:4f:9a:b8:
+                    5a:8c:8a:94:c8:69:4a:e7:7a:80:6a:5a:c5:f9:58:
+                    1e:43:7d:bd:e3:d1:79:4f:b8:00:33:77:31:ed:c1:
+                    aa:3f:a7:8a:5c:a4:dd:1a:98:0e:cc:02:ce:e7:41:
+                    05:f6:5c:fc:7e:e8:06:18:1f:57:ea:16:69:25:99:
+                    71:2d:b1:73:ff:36:f2:ee:bb:4a:0a:80:85:39:84:
+                    f8:8b:eb:d8:f5:ef:ff:9b:fe
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                7D:D4:B3:14:1D:F8:86:93:29:91:B3:B7:7F:76:DB:06:05:6B:63:44
+            X509v3 Authority Key Identifier: 
+                keyid:D0:C2:5B:D0:A4:D4:EB:05:FD:7C:4C:0E:A7:1E:2F:A0:CA:68:4F:3A
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:00
+
+    Signature Algorithm: md5WithRSAEncryption
+        76:b9:1c:89:97:28:3d:df:81:b8:29:fd:84:9c:e1:ae:19:db:
+        18:53:cc:87:dc:13:90:6c:f9:40:64:a4:23:92:f7:65:06:de:
+        b4:88:b0:c9:35:61:7d:d6:57:3e:de:3d:d5:83:6f:78:78:74:
+        cb:f6:84:0b:24:de:02:97:5e:51:b3:e7:8f:6a:e9:cb:5f:78:
+        f4:41:8d:75:55:a5:05:ae:f2:42:c5:ff:c4:39:06:ae:75:fa:
+        c2:2e:dd:3d:bc:12:c9:5b:a5:f0:18:e4:f4:33:2a:b9:cf:95:
+        38:b8:11:21:10:5a:3b:68:b8:e1:14:35:14:28:28:4b:a5:bb:
+        fd:20
+-----BEGIN CERTIFICATE-----
+MIIESTCCA7KgAwIBAgIBBzANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE2MTAzN1oXDTA4MDMwOTE2MTAzN1owZDELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRIwEAYDVQQDEwl3ZXJuZXJEU0EwggG4MIIBLAYHKoZIzjgEATCC
+AR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y
++r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG
+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML
+zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC
+Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9J
+KgOBhQACgYEA8Z19unyOuy3U7wbonY9V0lTV/TEKLeehELjMoD9gWgcETSziFIGm
+p0hPmrhajIqUyGlK53qAalrF+VgeQ32949F5T7gAM3cx7cGqP6eKXKTdGpgOzALO
+50EF9lz8fugGGB9X6hZpJZlxLbFz/zby7rtKCoCFOYT4i+vY9e//m/6jge4wgesw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFH3UsxQd+IaTKZGzt3922wYFa2NEMIGQBgNVHSME
+gYgwgYWAFNDCW9Ck1OsF/XxMDqceL6DKaE86oWqkaDBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggEAMA0GCSqG
+SIb3DQEBBAUAA4GBAHa5HImXKD3fgbgp/YSc4a4Z2xhTzIfcE5Bs+UBkpCOS92UG
+3rSIsMk1YX3WVz7ePdWDb3h4dMv2hAsk3gKXXlGz549q6ctfePRBjXVVpQWu8kLF
+/8Q5Bq51+sIu3T28EslbpfAY5PQzKrnPlTi4ESEQWjtouOEUNRQoKEulu/0g
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/08.pem b/keys/ca.db.certs/08.pem
new file mode 100644
index 0000000..9809308
--- /dev/null
+++ b/keys/ca.db.certs/08.pem
@@ -0,0 +1,65 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 8 (0x8)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:01:56 2006 GMT
+            Not After : Mar  9 17:01:56 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=werner
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1023 bit)
+                Modulus (1023 bit):
+                    72:0b:f1:36:fc:53:b6:20:5b:0e:1f:cc:2c:c6:3f:
+                    3e:f1:75:cc:25:4e:8f:ef:ec:b9:a0:70:95:ad:9a:
+                    6e:2c:03:1c:33:41:4b:4c:c3:22:5e:8d:96:4c:d9:
+                    cb:29:8b:0d:90:2d:7f:7c:1e:e6:27:dd:b1:cc:cc:
+                    b9:45:c0:99:56:4e:92:46:a1:92:ad:68:0c:7c:04:
+                    fd:50:1a:f0:08:9a:f3:56:4d:4b:55:cc:ac:95:cc:
+                    f2:4c:ce:40:e2:ad:63:fc:79:19:03:8f:cc:17:37:
+                    4f:4f:40:27:b2:84:83:41:3e:c9:7d:8a:17:44:6c:
+                    4c:38:09:63:a2:a0:08:3d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                E4:88:F1:D3:7B:E6:47:03:0F:95:C0:B6:91:1F:7F:15:6D:41:F1:84
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        26:5b:a1:b6:20:09:b4:c9:11:79:92:f9:d8:91:e1:52:75:18:
+        46:3f:47:87:59:69:e0:e5:da:ea:25:8a:d8:b3:8e:95:8f:f9:
+        43:c0:55:b1:24:cb:1b:1d:31:96:1b:a4:25:14:b6:20:8f:40:
+        a9:e8:f1:a5:2e:41:fc:1c:b8:23:1f:ee:aa:88:39:d0:9f:d0:
+        ce:29:05:f0:24:f0:02:5b:66:26:5f:49:c1:09:89:59:2a:95:
+        0a:86:70:b3:ba:14:2a:3a:9e:15:e7:18:69:b0:1e:e2:04:90:
+        3a:68:b6:f8:77:a8:98:c6:7a:b5:15:ee:87:fd:90:af:71:21:
+        a1:b8
+-----BEGIN CERTIFICATE-----
+MIIDMzCCApygAwIBAgIBCDANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDE1NloXDTA4MDMwOTE3MDE1NlowYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZ3ZXJuZXIwgZ4wDQYJKoZIhvcNAQEBBQADgYwA
+MIGIAoGAcgvxNvxTtiBbDh/MLMY/PvF1zCVOj+/suaBwla2abiwDHDNBS0zDIl6N
+lkzZyymLDZAtf3we5ifdsczMuUXAmVZOkkahkq1oDHwE/VAa8Aia81ZNS1XMrJXM
+8kzOQOKtY/x5GQOPzBc3T09AJ7KEg0E+yX2KF0RsTDgJY6KgCD0CAwEAAaOB9jCB
+8zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU5Ijx03vmRwMPlcC2kR9/FW1B8YQwgZgGA1Ud
+IwSBkDCBjYAU2ZUqSj920IeosfD/hLjAehG5MXahaqRoMGYxCzAJBgNVBAYTAkRF
+MQ8wDQYDVQQIEwZCYXllcm4xDzANBgNVBAcTBk11bmljaDENMAsGA1UEChMESG9t
+ZTEVMBMGA1UECxMMQXBhY2hlIFdTUzRKMQ8wDQYDVQQDEwZXZXJuZXKCCQDmeABh
+B7zaRjANBgkqhkiG9w0BAQQFAAOBgQAmW6G2IAm0yRF5kvnYkeFSdRhGP0eHWWng
+5drqJYrYs46Vj/lDwFWxJMsbHTGWG6QlFLYgj0Cp6PGlLkH8HLgjH+6qiDnQn9DO
+KQXwJPACW2YmX0nBCYlZKpUKhnCzuhQqOp4V5xhpsB7iBJA6aLb4d6iYxnq1Fe6H
+/ZCvcSGhuA==
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/09.pem b/keys/ca.db.certs/09.pem
new file mode 100644
index 0000000..77d847d
--- /dev/null
+++ b/keys/ca.db.certs/09.pem
@@ -0,0 +1,93 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 9 (0x9)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:02:07 2006 GMT
+            Not After : Mar  9 17:02:07 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=wernerDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:f1:9d:7d:ba:7c:8e:bb:2d:d4:ef:06:e8:9d:8f:
+                    55:d2:54:d5:fd:31:0a:2d:e7:a1:10:b8:cc:a0:3f:
+                    60:5a:07:04:4d:2c:e2:14:81:a6:a7:48:4f:9a:b8:
+                    5a:8c:8a:94:c8:69:4a:e7:7a:80:6a:5a:c5:f9:58:
+                    1e:43:7d:bd:e3:d1:79:4f:b8:00:33:77:31:ed:c1:
+                    aa:3f:a7:8a:5c:a4:dd:1a:98:0e:cc:02:ce:e7:41:
+                    05:f6:5c:fc:7e:e8:06:18:1f:57:ea:16:69:25:99:
+                    71:2d:b1:73:ff:36:f2:ee:bb:4a:0a:80:85:39:84:
+                    f8:8b:eb:d8:f5:ef:ff:9b:fe
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                7D:D4:B3:14:1D:F8:86:93:29:91:B3:B7:7F:76:DB:06:05:6B:63:44
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        23:fa:01:b9:01:68:54:a4:8a:51:26:0b:b5:7c:17:5b:f0:1c:
+        03:05:f8:30:7d:ac:56:1e:46:18:ad:bc:42:cd:52:85:14:43:
+        77:2a:ee:ee:66:cc:05:96:b4:37:af:25:04:1e:b5:f8:bb:34:
+        db:2e:b8:3e:2c:58:00:57:92:b4:91:3b:40:e3:e0:f5:9b:7e:
+        b2:10:28:97:ee:78:34:9f:70:48:22:bb:3f:14:05:a6:34:fb:
+        0c:3e:58:7c:91:7e:48:70:1e:9d:fd:e5:0b:32:6a:96:83:7d:
+        a4:ce:4f:ac:54:a3:fa:8f:cb:f0:3b:a3:29:f2:9e:c3:23:5a:
+        10:ab
+-----BEGIN CERTIFICATE-----
+MIIEUTCCA7qgAwIBAgIBCTANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDIwN1oXDTA4MDMwOTE3MDIwN1owZDELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRIwEAYDVQQDEwl3ZXJuZXJEU0EwggG4MIIBLAYHKoZIzjgEATCC
+AR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y
++r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG
+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML
+zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC
+Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9J
+KgOBhQACgYEA8Z19unyOuy3U7wbonY9V0lTV/TEKLeehELjMoD9gWgcETSziFIGm
+p0hPmrhajIqUyGlK53qAalrF+VgeQ32949F5T7gAM3cx7cGqP6eKXKTdGpgOzALO
+50EF9lz8fugGGB9X6hZpJZlxLbFz/zby7rtKCoCFOYT4i+vY9e//m/6jgfYwgfMw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFH3UsxQd+IaTKZGzt3922wYFa2NEMIGYBgNVHSME
+gZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngAYQe8
+2kYwDQYJKoZIhvcNAQEEBQADgYEAI/oBuQFoVKSKUSYLtXwXW/AcAwX4MH2sVh5G
+GK28Qs1ShRRDdyru7mbMBZa0N68lBB61+Ls02y64PixYAFeStJE7QOPg9Zt+shAo
+l+54NJ9wSCK7PxQFpjT7DD5YfJF+SHAenf3lCzJqloN9pM5PrFSj+o/L8DujKfKe
+wyNaEKs=
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/0A.pem b/keys/ca.db.certs/0A.pem
new file mode 100644
index 0000000..555d2c6
--- /dev/null
+++ b/keys/ca.db.certs/0A.pem
@@ -0,0 +1,65 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 10 (0xa)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:04:55 2006 GMT
+            Not After : Mar  9 17:04:55 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=werner
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1023 bit)
+                Modulus (1023 bit):
+                    72:0b:f1:36:fc:53:b6:20:5b:0e:1f:cc:2c:c6:3f:
+                    3e:f1:75:cc:25:4e:8f:ef:ec:b9:a0:70:95:ad:9a:
+                    6e:2c:03:1c:33:41:4b:4c:c3:22:5e:8d:96:4c:d9:
+                    cb:29:8b:0d:90:2d:7f:7c:1e:e6:27:dd:b1:cc:cc:
+                    b9:45:c0:99:56:4e:92:46:a1:92:ad:68:0c:7c:04:
+                    fd:50:1a:f0:08:9a:f3:56:4d:4b:55:cc:ac:95:cc:
+                    f2:4c:ce:40:e2:ad:63:fc:79:19:03:8f:cc:17:37:
+                    4f:4f:40:27:b2:84:83:41:3e:c9:7d:8a:17:44:6c:
+                    4c:38:09:63:a2:a0:08:3d
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                E4:88:F1:D3:7B:E6:47:03:0F:95:C0:B6:91:1F:7F:15:6D:41:F1:84
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        27:b1:a2:69:2d:50:38:f6:9c:b1:bd:b9:81:a3:c3:60:25:0f:
+        7f:82:b9:63:16:7a:0c:2b:cc:fa:45:78:ff:9b:b9:f0:96:aa:
+        28:d0:c0:98:d5:fe:bd:81:79:1e:2d:96:8e:a3:0a:bb:d8:ca:
+        cf:c4:cb:d6:56:3a:cf:a7:a8:08:26:dd:97:54:29:9e:eb:93:
+        8d:87:9d:3b:5c:22:9f:94:b9:43:de:e1:05:74:67:00:f5:d1:
+        ca:1f:70:26:00:13:63:01:25:6c:ed:61:6e:20:19:76:68:21:
+        ef:0a:f0:42:e2:2c:1c:13:23:82:7c:d4:2e:a9:38:0c:73:07:
+        a8:2c
+-----BEGIN CERTIFICATE-----
+MIIDMzCCApygAwIBAgIBCjANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDQ1NVoXDTA4MDMwOTE3MDQ1NVowYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZ3ZXJuZXIwgZ4wDQYJKoZIhvcNAQEBBQADgYwA
+MIGIAoGAcgvxNvxTtiBbDh/MLMY/PvF1zCVOj+/suaBwla2abiwDHDNBS0zDIl6N
+lkzZyymLDZAtf3we5ifdsczMuUXAmVZOkkahkq1oDHwE/VAa8Aia81ZNS1XMrJXM
+8kzOQOKtY/x5GQOPzBc3T09AJ7KEg0E+yX2KF0RsTDgJY6KgCD0CAwEAAaOB9jCB
+8zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD
+ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU5Ijx03vmRwMPlcC2kR9/FW1B8YQwgZgGA1Ud
+IwSBkDCBjYAU2ZUqSj920IeosfD/hLjAehG5MXahaqRoMGYxCzAJBgNVBAYTAkRF
+MQ8wDQYDVQQIEwZCYXllcm4xDzANBgNVBAcTBk11bmljaDENMAsGA1UEChMESG9t
+ZTEVMBMGA1UECxMMQXBhY2hlIFdTUzRKMQ8wDQYDVQQDEwZXZXJuZXKCCQDmeABh
+B7zaRjANBgkqhkiG9w0BAQQFAAOBgQAnsaJpLVA49pyxvbmBo8NgJQ9/grljFnoM
+K8z6RXj/m7nwlqoo0MCY1f69gXkeLZaOowq72MrPxMvWVjrPp6gIJt2XVCme65ON
+h507XCKflLlD3uEFdGcA9dHKH3AmABNjASVs7WFuIBl2aCHvCvBC4iwcEyOCfNQu
+qTgMcweoLA==
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/0B.pem b/keys/ca.db.certs/0B.pem
new file mode 100644
index 0000000..c4fdb92
--- /dev/null
+++ b/keys/ca.db.certs/0B.pem
@@ -0,0 +1,93 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 11 (0xb)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:05:01 2006 GMT
+            Not After : Mar  9 17:05:01 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=wernerDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:f1:9d:7d:ba:7c:8e:bb:2d:d4:ef:06:e8:9d:8f:
+                    55:d2:54:d5:fd:31:0a:2d:e7:a1:10:b8:cc:a0:3f:
+                    60:5a:07:04:4d:2c:e2:14:81:a6:a7:48:4f:9a:b8:
+                    5a:8c:8a:94:c8:69:4a:e7:7a:80:6a:5a:c5:f9:58:
+                    1e:43:7d:bd:e3:d1:79:4f:b8:00:33:77:31:ed:c1:
+                    aa:3f:a7:8a:5c:a4:dd:1a:98:0e:cc:02:ce:e7:41:
+                    05:f6:5c:fc:7e:e8:06:18:1f:57:ea:16:69:25:99:
+                    71:2d:b1:73:ff:36:f2:ee:bb:4a:0a:80:85:39:84:
+                    f8:8b:eb:d8:f5:ef:ff:9b:fe
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                7D:D4:B3:14:1D:F8:86:93:29:91:B3:B7:7F:76:DB:06:05:6B:63:44
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        a9:ce:af:60:82:7e:95:4f:e8:b8:06:a3:9e:c2:1b:3a:45:f1:
+        d7:27:c5:52:90:fe:35:e5:b0:33:c7:52:f7:4e:a5:2d:9b:76:
+        22:d1:c0:e2:03:40:0c:4c:62:99:28:62:41:58:0d:27:8f:44:
+        3a:71:8f:f9:4b:14:44:90:2e:01:6c:4c:17:e3:2a:ac:f0:58:
+        a2:3d:e8:91:7c:8a:a2:58:2f:26:b4:c3:b7:c3:85:69:66:5a:
+        53:da:e7:16:61:7b:0d:13:d7:ba:5e:32:08:e2:ae:64:63:cc:
+        ea:c7:13:be:bb:47:fd:af:ed:e8:da:a4:bd:60:25:41:8c:44:
+        9b:89
+-----BEGIN CERTIFICATE-----
+MIIEUTCCA7qgAwIBAgIBCzANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDUwMVoXDTA4MDMwOTE3MDUwMVowZDELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRIwEAYDVQQDEwl3ZXJuZXJEU0EwggG4MIIBLAYHKoZIzjgEATCC
+AR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y
++r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG
+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML
+zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC
+Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9J
+KgOBhQACgYEA8Z19unyOuy3U7wbonY9V0lTV/TEKLeehELjMoD9gWgcETSziFIGm
+p0hPmrhajIqUyGlK53qAalrF+VgeQ32949F5T7gAM3cx7cGqP6eKXKTdGpgOzALO
+50EF9lz8fugGGB9X6hZpJZlxLbFz/zby7rtKCoCFOYT4i+vY9e//m/6jgfYwgfMw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFH3UsxQd+IaTKZGzt3922wYFa2NEMIGYBgNVHSME
+gZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngAYQe8
+2kYwDQYJKoZIhvcNAQEEBQADgYEAqc6vYIJ+lU/ouAajnsIbOkXx1yfFUpD+NeWw
+M8dS906lLZt2ItHA4gNADEximShiQVgNJ49EOnGP+UsURJAuAWxMF+MqrPBYoj3o
+kXyKolgvJrTDt8OFaWZaU9rnFmF7DRPXul4yCOKuZGPM6scTvrtH/a/t6NqkvWAl
+QYxEm4k=
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/0C.pem b/keys/ca.db.certs/0C.pem
new file mode 100644
index 0000000..211f7c5
--- /dev/null
+++ b/keys/ca.db.certs/0C.pem
@@ -0,0 +1,65 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 12 (0xc)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:07:22 2006 GMT
+            Not After : Mar  9 17:07:22 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=Werner
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:90:a9:4a:94:71:77:ca:03:bd:df:4d:3d:1c:50:
+                    9a:a0:b4:a1:30:3f:34:2d:44:aa:d5:0a:b1:42:46:
+                    5b:c2:d1:3b:b3:66:b6:82:8c:d0:9b:43:b7:8b:06:
+                    7f:66:0e:e7:b2:0e:07:59:c0:b2:9f:77:3b:a6:ed:
+                    39:e0:b4:82:67:aa:de:2a:ba:66:0d:a2:b3:4c:47:
+                    21:ff:33:b2:82:b6:68:83:fa:9d:d1:e0:04:be:6b:
+                    5a:f8:a9:e8:77:76:1f:06:92:26:12:f9:59:1e:65:
+                    45:8c:a5:29:55:72:5b:b4:1a:6e:d2:d8:79:9b:98:
+                    6f:94:88:90:e8:aa:a2:72:7f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C0:92:B0:AC:F1:AA:27:F4:C7:28:77:A2:0E:41:80:7A:B7:9F:5B:F0
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        cf:54:02:2d:7c:bf:3c:b2:8c:d3:54:16:9d:57:e0:fa:ef:4f:
+        fe:18:72:18:70:08:5d:8d:84:15:39:fa:02:a6:71:85:95:e7:
+        0d:7c:c2:69:24:f8:35:ba:ee:a1:2e:c2:a7:31:cb:95:71:20:
+        98:31:e4:60:52:94:f6:06:cc:0e:e0:b8:ae:27:a0:18:6e:eb:
+        bc:f1:2d:2d:90:ba:25:f6:86:de:2b:e2:bc:c8:d2:6e:9f:a4:
+        e2:d9:ad:94:49:9d:88:fc:93:b1:2c:72:77:a5:49:7d:3a:6e:
+        62:ba:c4:13:cc:ff:90:ac:0d:8d:85:65:0f:36:56:8f:04:7a:
+        74:b9
+-----BEGIN CERTIFICATE-----
+MIIDNDCCAp2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDcyMloXDTA4MDMwOTE3MDcyMlowYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAJCpSpRxd8oDvd9NPRxQmqC0oTA/NC1EqtUKsUJGW8LRO7NmtoKM0JtD
+t4sGf2YO57IOB1nAsp93O6btOeC0gmeq3iq6Zg2is0xHIf8zsoK2aIP6ndHgBL5r
+Wvip6Hd2HwaSJhL5WR5lRYylKVVyW7QabtLYeZuYb5SIkOiqonJ/AgMBAAGjgfYw
+gfMwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFMCSsKzxqif0xyh3og5BgHq3n1vwMIGYBgNV
+HSMEgZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJE
+RTEPMA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhv
+bWUxFTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngA
+YQe82kYwDQYJKoZIhvcNAQEEBQADgYEAz1QCLXy/PLKM01QWnVfg+u9P/hhyGHAI
+XY2EFTn6AqZxhZXnDXzCaST4NbruoS7CpzHLlXEgmDHkYFKU9gbMDuC4riegGG7r
+vPEtLZC6JfaG3ivivMjSbp+k4tmtlEmdiPyTsSxyd6VJfTpuYrrEE8z/kKwNjYVl
+DzZWjwR6dLk=
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.certs/0D.pem b/keys/ca.db.certs/0D.pem
new file mode 100644
index 0000000..8ec586d
--- /dev/null
+++ b/keys/ca.db.certs/0D.pem
@@ -0,0 +1,93 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 13 (0xd)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:07:29 2006 GMT
+            Not After : Mar  9 17:07:29 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=WernerDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:88:da:f5:b5:f9:81:6d:2d:19:c6:ee:63:bc:15:
+                    e2:08:e3:77:18:4b:20:84:ea:3d:5f:82:a4:65:73:
+                    8b:4a:e3:d6:42:70:7e:5b:da:91:71:db:01:2a:dd:
+                    0c:1b:bb:22:46:31:f9:09:9b:e4:6a:ff:00:f5:dd:
+                    2b:f6:ea:9e:ca:e3:0a:aa:1c:5e:8f:be:6d:ab:57:
+                    60:d0:7f:1d:b4:91:40:d5:44:c4:b9:29:49:a4:18:
+                    fd:31:7a:af:d2:b5:df:9f:c4:20:78:8e:a5:48:b0:
+                    f1:e4:92:67:61:d1:be:76:b2:d7:d9:d9:40:f8:f1:
+                    7e:d2:51:62:3a:02:eb:2c:2d
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                93:A5:0D:37:7D:E9:1F:88:58:29:D5:8E:21:CE:E1:E4:17:5C:ED:DC
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        81:07:ab:24:e4:30:da:49:e0:30:8f:63:ca:54:65:af:37:2c:
+        f8:3e:b0:d2:88:60:6d:b9:16:e9:90:e5:db:d6:c2:db:79:0a:
+        2c:1c:fb:d3:cb:f2:a7:fb:60:dc:ee:1c:92:a6:fc:58:da:3c:
+        85:3e:21:05:c7:57:74:20:37:e1:3e:d7:19:de:60:5a:0d:dc:
+        60:aa:14:40:8f:e1:cf:3b:be:97:cb:18:22:19:8f:43:e7:37:
+        0f:68:f8:d9:89:98:b3:8d:b1:76:a3:e7:00:b3:c5:68:38:78:
+        da:d3:b5:63:b2:0b:0a:57:f5:98:0c:de:01:09:5b:8b:ee:12:
+        17:8e
+-----BEGIN CERTIFICATE-----
+MIIEUTCCA7qgAwIBAgIBDTANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDcyOVoXDTA4MDMwOTE3MDcyOVowZDELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRIwEAYDVQQDEwlXZXJuZXJEU0EwggG4MIIBLAYHKoZIzjgEATCC
+AR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y
++r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG
+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML
+zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC
+Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9J
+KgOBhQACgYEAiNr1tfmBbS0Zxu5jvBXiCON3GEsghOo9X4KkZXOLSuPWQnB+W9qR
+cdsBKt0MG7siRjH5CZvkav8A9d0r9uqeyuMKqhxej75tq1dg0H8dtJFA1UTEuSlJ
+pBj9MXqv0rXfn8QgeI6lSLDx5JJnYdG+drLX2dlA+PF+0lFiOgLrLC2jgfYwgfMw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFJOlDTd96R+IWCnVjiHO4eQXXO3cMIGYBgNVHSME
+gZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngAYQe8
+2kYwDQYJKoZIhvcNAQEEBQADgYEAgQerJOQw2kngMI9jylRlrzcs+D6w0ohgbbkW
+6ZDl29bC23kKLBz708vyp/tg3O4ckqb8WNo8hT4hBcdXdCA34T7XGd5gWg3cYKoU
+QI/hzzu+l8sYIhmPQ+c3D2j42YmYs42xdqPnALPFaDh42tO1Y7ILClf1mAzeAQlb
+i+4SF44=
+-----END CERTIFICATE-----
diff --git a/keys/ca.db.index b/keys/ca.db.index
new file mode 100644
index 0000000..1ac0abc
--- /dev/null
+++ b/keys/ca.db.index
@@ -0,0 +1,13 @@
+E	050228105117Z		01	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=werner
+E	050228120029Z		02	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerd
+E	050307093155Z		03	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerdDSA
+V	060309222536Z		04	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerdDSA
+V	060309223016Z		05	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerd
+V	080309161024Z		06	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=werner
+V	080309161037Z		07	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerDSA
+V	080309170156Z		08	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=werner
+V	080309170207Z		09	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerDSA
+V	080309170455Z		0A	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=werner
+V	080309170501Z		0B	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=wernerDSA
+V	080309170722Z		0C	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=Werner
+V	080309170729Z		0D	unknown	/C=DE/ST=Bayern/L=Munich/O=Apache/OU=WSS4J/CN=WernerDSA
diff --git a/keys/ca.db.index.attr b/keys/ca.db.index.attr
new file mode 100644
index 0000000..3a7e39e
--- /dev/null
+++ b/keys/ca.db.index.attr
@@ -0,0 +1 @@
+unique_subject = no
diff --git a/keys/ca.db.serial b/keys/ca.db.serial
new file mode 100644
index 0000000..ff470b0
--- /dev/null
+++ b/keys/ca.db.serial
@@ -0,0 +1 @@
+0E
diff --git a/keys/ca.key b/keys/ca.key
new file mode 100644
index 0000000..9909879
--- /dev/null
+++ b/keys/ca.key
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,6DA21E161F9EF0BF
+
+QlIo6z9lYaqLSYm66f/4PgWsoBxls2uJkAp0IgQfxqftC9cZpkyYOeD//2JYtyWR
+/09V6Nx4tcRF3JPCXx+BoX11oNZr1ze+1Tgt6ZmIETrKrW4oS69W43q0JiKcHYcP
+3gTZASnBU+KkPEVcyN+XNP/6UURP0Y5P+IgQj8FEi0LSh3RVGXLwsVmeXo0vkGvH
++U+GrGW4h25udkqt62O2gi34XdBBuIMUaLl9wMJ+M/oTzP91v213JGMoVLd3N7Cf
+S24rPb/pabcz+wIPKW2RU8Fgssun4pIRIjOujbzONo7OgoeIXM+n4zNyFa34E5ub
+iLKYOiS8pFkWLKXPxSRTAweWKfyoWNYaGbsSxrJHMLiRplHlHveJdbBJ5Y1h7OEs
+9+UqxZNXX1lMyzueC5TewoSUEkiFw+5Fmrw9N3m5v5oZOdFD/dWeysHimUPQS+zg
+sn7mnY/M3VbPCMWbK4RLs3/ABZxFhmMDZWXRFXSXk+jXqt2mWBKJPALBTbNHFDsm
+05fX0HD+IjRtODSjluK9dpnegS8EdJT5yG2J/Jhr2MzSPe2PlyvnrMXZ+MDWz5XJ
+TWLsn5c3A6FsvIFbCRb/QxfZldT6d/33A6vxSpYHOfti4de7Yw32TlRmYr8F3DLA
+BCHiVcCKzMRiJAbYRsCyKWWttdKV9fixNDhzvDNboMJf/duum8op4ALKaZsaBvq6
+BfY6kmckqStZDJs/ytlnjDnAPBBpJML+vBIbo24n1d3X1mvIVwCADqMspfqr3Ukg
+hACyMhPB+fNx+mUqgW+Sf77ffD62ktyoR5StxsbwJuZqqqghOjAvTg==
+-----END RSA PRIVATE KEY-----
diff --git a/keys/cert.crt b/keys/cert.crt
new file mode 100644
index 0000000..69985b7
--- /dev/null
+++ b/keys/cert.crt
Binary files differ
diff --git a/keys/cert.pem b/keys/cert.pem
new file mode 100644
index 0000000..211f7c5
--- /dev/null
+++ b/keys/cert.pem
@@ -0,0 +1,65 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 12 (0xc)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:07:22 2006 GMT
+            Not After : Mar  9 17:07:22 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=Werner
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:90:a9:4a:94:71:77:ca:03:bd:df:4d:3d:1c:50:
+                    9a:a0:b4:a1:30:3f:34:2d:44:aa:d5:0a:b1:42:46:
+                    5b:c2:d1:3b:b3:66:b6:82:8c:d0:9b:43:b7:8b:06:
+                    7f:66:0e:e7:b2:0e:07:59:c0:b2:9f:77:3b:a6:ed:
+                    39:e0:b4:82:67:aa:de:2a:ba:66:0d:a2:b3:4c:47:
+                    21:ff:33:b2:82:b6:68:83:fa:9d:d1:e0:04:be:6b:
+                    5a:f8:a9:e8:77:76:1f:06:92:26:12:f9:59:1e:65:
+                    45:8c:a5:29:55:72:5b:b4:1a:6e:d2:d8:79:9b:98:
+                    6f:94:88:90:e8:aa:a2:72:7f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C0:92:B0:AC:F1:AA:27:F4:C7:28:77:A2:0E:41:80:7A:B7:9F:5B:F0
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        cf:54:02:2d:7c:bf:3c:b2:8c:d3:54:16:9d:57:e0:fa:ef:4f:
+        fe:18:72:18:70:08:5d:8d:84:15:39:fa:02:a6:71:85:95:e7:
+        0d:7c:c2:69:24:f8:35:ba:ee:a1:2e:c2:a7:31:cb:95:71:20:
+        98:31:e4:60:52:94:f6:06:cc:0e:e0:b8:ae:27:a0:18:6e:eb:
+        bc:f1:2d:2d:90:ba:25:f6:86:de:2b:e2:bc:c8:d2:6e:9f:a4:
+        e2:d9:ad:94:49:9d:88:fc:93:b1:2c:72:77:a5:49:7d:3a:6e:
+        62:ba:c4:13:cc:ff:90:ac:0d:8d:85:65:0f:36:56:8f:04:7a:
+        74:b9
+-----BEGIN CERTIFICATE-----
+MIIDNDCCAp2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDcyMloXDTA4MDMwOTE3MDcyMlowYTELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+MIGJAoGBAJCpSpRxd8oDvd9NPRxQmqC0oTA/NC1EqtUKsUJGW8LRO7NmtoKM0JtD
+t4sGf2YO57IOB1nAsp93O6btOeC0gmeq3iq6Zg2is0xHIf8zsoK2aIP6ndHgBL5r
+Wvip6Hd2HwaSJhL5WR5lRYylKVVyW7QabtLYeZuYb5SIkOiqonJ/AgMBAAGjgfYw
+gfMwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFMCSsKzxqif0xyh3og5BgHq3n1vwMIGYBgNV
+HSMEgZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJE
+RTEPMA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhv
+bWUxFTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngA
+YQe82kYwDQYJKoZIhvcNAQEEBQADgYEAz1QCLXy/PLKM01QWnVfg+u9P/hhyGHAI
+XY2EFTn6AqZxhZXnDXzCaST4NbruoS7CpzHLlXEgmDHkYFKU9gbMDuC4riegGG7r
+vPEtLZC6JfaG3ivivMjSbp+k4tmtlEmdiPyTsSxyd6VJfTpuYrrEE8z/kKwNjYVl
+DzZWjwR6dLk=
+-----END CERTIFICATE-----
diff --git a/keys/cert.req b/keys/cert.req
new file mode 100644
index 0000000..ff86f63
--- /dev/null
+++ b/keys/cert.req
@@ -0,0 +1,10 @@
+-----BEGIN NEW CERTIFICATE REQUEST-----

+MIIBoTCCAQoCAQAwYTELMAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVu

+aWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNVBAsTBVdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIwgZ8w

+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJCpSpRxd8oDvd9NPRxQmqC0oTA/NC1EqtUKsUJGW8LR

+O7NmtoKM0JtDt4sGf2YO57IOB1nAsp93O6btOeC0gmeq3iq6Zg2is0xHIf8zsoK2aIP6ndHgBL5r

+Wvip6Hd2HwaSJhL5WR5lRYylKVVyW7QabtLYeZuYb5SIkOiqonJ/AgMBAAGgADANBgkqhkiG9w0B

+AQQFAAOBgQB2pcJOOkzg4p3NKGZq7zydZ5KzZQMx1yfajJ9Hcw80Sh7xAYa4spdoNP95JLQ3S1TV

+qp+Jk2PtJdgqqLWp8vp2jrUeda5GZtsgr0Cx9Eyt5ucrSZHPZ9Yxh+FxDtsCayTGhdCQmmLVu/KY

+A3sSpYPjArZTJrQnTabV0XtFjRybKQ==

+-----END NEW CERTIFICATE REQUEST-----

diff --git a/keys/certDSA.crt b/keys/certDSA.crt
new file mode 100644
index 0000000..6158503
--- /dev/null
+++ b/keys/certDSA.crt
Binary files differ
diff --git a/keys/certDSA.pem b/keys/certDSA.pem
new file mode 100644
index 0000000..8ec586d
--- /dev/null
+++ b/keys/certDSA.pem
@@ -0,0 +1,93 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 13 (0xd)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=DE, ST=Bayern, L=Munich, O=Home, OU=Apache WSS4J, CN=Werner
+        Validity
+            Not Before: Mar 10 17:07:29 2006 GMT
+            Not After : Mar  9 17:07:29 2008 GMT
+        Subject: C=DE, ST=Bayern, L=Munich, O=Apache, OU=WSS4J, CN=WernerDSA
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    00:88:da:f5:b5:f9:81:6d:2d:19:c6:ee:63:bc:15:
+                    e2:08:e3:77:18:4b:20:84:ea:3d:5f:82:a4:65:73:
+                    8b:4a:e3:d6:42:70:7e:5b:da:91:71:db:01:2a:dd:
+                    0c:1b:bb:22:46:31:f9:09:9b:e4:6a:ff:00:f5:dd:
+                    2b:f6:ea:9e:ca:e3:0a:aa:1c:5e:8f:be:6d:ab:57:
+                    60:d0:7f:1d:b4:91:40:d5:44:c4:b9:29:49:a4:18:
+                    fd:31:7a:af:d2:b5:df:9f:c4:20:78:8e:a5:48:b0:
+                    f1:e4:92:67:61:d1:be:76:b2:d7:d9:d9:40:f8:f1:
+                    7e:d2:51:62:3a:02:eb:2c:2d
+                P:   
+                    00:fd:7f:53:81:1d:75:12:29:52:df:4a:9c:2e:ec:
+                    e4:e7:f6:11:b7:52:3c:ef:44:00:c3:1e:3f:80:b6:
+                    51:26:69:45:5d:40:22:51:fb:59:3d:8d:58:fa:bf:
+                    c5:f5:ba:30:f6:cb:9b:55:6c:d7:81:3b:80:1d:34:
+                    6f:f2:66:60:b7:6b:99:50:a5:a4:9f:9f:e8:04:7b:
+                    10:22:c2:4f:bb:a9:d7:fe:b7:c6:1b:f8:3b:57:e7:
+                    c6:a8:a6:15:0f:04:fb:83:f6:d3:c5:1e:c3:02:35:
+                    54:13:5a:16:91:32:f6:75:f3:ae:2b:61:d7:2a:ef:
+                    f2:22:03:19:9d:d1:48:01:c7
+                Q:   
+                    00:97:60:50:8f:15:23:0b:cc:b2:92:b9:82:a2:eb:
+                    84:0b:f0:58:1c:f5
+                G:   
+                    00:f7:e1:a0:85:d6:9b:3d:de:cb:bc:ab:5c:36:b8:
+                    57:b9:79:94:af:bb:fa:3a:ea:82:f9:57:4c:0b:3d:
+                    07:82:67:51:59:57:8e:ba:d4:59:4f:e6:71:07:10:
+                    81:80:b4:49:16:71:23:e8:4c:28:16:13:b7:cf:09:
+                    32:8c:c8:a6:e1:3c:16:7a:8b:54:7c:8d:28:e0:a3:
+                    ae:1e:2b:b3:a6:75:91:6e:a3:7f:0b:fa:21:35:62:
+                    f1:fb:62:7a:01:24:3b:cc:a4:f1:be:a8:51:90:89:
+                    a8:83:df:e1:5a:e5:9f:06:92:8b:66:5e:80:7b:55:
+                    25:64:01:4c:3b:fe:cf:49:2a
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                93:A5:0D:37:7D:E9:1F:88:58:29:D5:8E:21:CE:E1:E4:17:5C:ED:DC
+            X509v3 Authority Key Identifier: 
+                keyid:D9:95:2A:4A:3F:76:D0:87:A8:B1:F0:FF:84:B8:C0:7A:11:B9:31:76
+                DirName:/C=DE/ST=Bayern/L=Munich/O=Home/OU=Apache WSS4J/CN=Werner
+                serial:E6:78:00:61:07:BC:DA:46
+
+    Signature Algorithm: md5WithRSAEncryption
+        81:07:ab:24:e4:30:da:49:e0:30:8f:63:ca:54:65:af:37:2c:
+        f8:3e:b0:d2:88:60:6d:b9:16:e9:90:e5:db:d6:c2:db:79:0a:
+        2c:1c:fb:d3:cb:f2:a7:fb:60:dc:ee:1c:92:a6:fc:58:da:3c:
+        85:3e:21:05:c7:57:74:20:37:e1:3e:d7:19:de:60:5a:0d:dc:
+        60:aa:14:40:8f:e1:cf:3b:be:97:cb:18:22:19:8f:43:e7:37:
+        0f:68:f8:d9:89:98:b3:8d:b1:76:a3:e7:00:b3:c5:68:38:78:
+        da:d3:b5:63:b2:0b:0a:57:f5:98:0c:de:01:09:5b:8b:ee:12:
+        17:8e
+-----BEGIN CERTIFICATE-----
+MIIEUTCCA7qgAwIBAgIBDTANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA2MDMx
+MDE3MDcyOVoXDTA4MDMwOTE3MDcyOVowZDELMAkGA1UEBhMCREUxDzANBgNVBAgT
+BkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNV
+BAsTBVdTUzRKMRIwEAYDVQQDEwlXZXJuZXJEU0EwggG4MIIBLAYHKoZIzjgEATCC
+AR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y
++r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG
+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML
+zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeC
+Z1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7Om
+dZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9J
+KgOBhQACgYEAiNr1tfmBbS0Zxu5jvBXiCON3GEsghOo9X4KkZXOLSuPWQnB+W9qR
+cdsBKt0MG7siRjH5CZvkav8A9d0r9uqeyuMKqhxej75tq1dg0H8dtJFA1UTEuSlJ
+pBj9MXqv0rXfn8QgeI6lSLDx5JJnYdG+drLX2dlA+PF+0lFiOgLrLC2jgfYwgfMw
+CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFJOlDTd96R+IWCnVjiHO4eQXXO3cMIGYBgNVHSME
+gZAwgY2AFNmVKko/dtCHqLHw/4S4wHoRuTF2oWqkaDBmMQswCQYDVQQGEwJERTEP
+MA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx
+FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkA5ngAYQe8
+2kYwDQYJKoZIhvcNAQEEBQADgYEAgQerJOQw2kngMI9jylRlrzcs+D6w0ohgbbkW
+6ZDl29bC23kKLBz708vyp/tg3O4ckqb8WNo8hT4hBcdXdCA34T7XGd5gWg3cYKoU
+QI/hzzu+l8sYIhmPQ+c3D2j42YmYs42xdqPnALPFaDh42tO1Y7ILClf1mAzeAQlb
+i+4SF44=
+-----END CERTIFICATE-----
diff --git a/keys/certDSA.req b/keys/certDSA.req
new file mode 100644
index 0000000..bcc15fa
--- /dev/null
+++ b/keys/certDSA.req
@@ -0,0 +1,13 @@
+-----BEGIN NEW CERTIFICATE REQUEST-----

+MIICajCCAicCAQAwZDELMAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVu

+aWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNVBAsTBVdTUzRKMRIwEAYDVQQDEwlXZXJuZXJEU0Ew

+ggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlF

+XUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fG

+qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL

+8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkW

+cSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD

+3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhQACgYEAiNr1tfmBbS0Zxu5jvBXiCON3GEsghOo9X4Kk

+ZXOLSuPWQnB+W9qRcdsBKt0MG7siRjH5CZvkav8A9d0r9uqeyuMKqhxej75tq1dg0H8dtJFA1UTE

+uSlJpBj9MXqv0rXfn8QgeI6lSLDx5JJnYdG+drLX2dlA+PF+0lFiOgLrLC2gADALBgcqhkjOOAQD

+BQADMAAwLQIVAIGO3HM6vKCNKMDVUOB7/bjGYknUAhQwwoOZb4xAeUhfx4lmZs1NCd3rzg==

+-----END NEW CERTIFICATE REQUEST-----

diff --git a/keys/genCAKey.sh b/keys/genCAKey.sh
new file mode 100644
index 0000000..ed3d34b
--- /dev/null
+++ b/keys/genCAKey.sh
@@ -0,0 +1 @@
+openssl req -x509 -newkey rsa:1024 -keyout CAKey.pem -out CA.pem -config ca.config

diff --git a/keys/genCertRequest.sh b/keys/genCertRequest.sh
new file mode 100644
index 0000000..8ec4e03
--- /dev/null
+++ b/keys/genCertRequest.sh
@@ -0,0 +1,3 @@
+# Export the key as a request (use security as the password)

+"$JAVA_HOME/bin/keytool" -keystore wss4j.keystore -alias wss4jCert -certreq -file cert.req

+"$JAVA_HOME/bin/keytool" -keystore wss4j.keystore -alias wss4jCertDSA -certreq -file certDSA.req
\ No newline at end of file
diff --git a/keys/genKeystore.sh b/keys/genKeystore.sh
new file mode 100644
index 0000000..af959d0
--- /dev/null
+++ b/keys/genKeystore.sh
@@ -0,0 +1,9 @@
+#

+# Clean out the server and client keystores

+# rm wss4j.keystore

+

+# Generate the key that will be used for wss4j

+# (use security as the password)

+"$JAVA_HOME/bin/keytool" -genkey -alias wss4jCert -keyalg RSA -keystore wss4j.keystore -dname "CN=Werner,OU=WSS4J,O=Apache,L=Munich,ST=Bayern,C=DE"

+"$JAVA_HOME/bin/keytool" -genkey -alias wss4jCertDSA -keystore wss4j.keystore -dname "CN=WernerDSA,OU=WSS4J,O=Apache,L=Munich,ST=Bayern,C=DE"

+

diff --git a/keys/k.bat b/keys/k.bat
new file mode 100644
index 0000000..c951c5d
--- /dev/null
+++ b/keys/k.bat
@@ -0,0 +1 @@
+keytool -genkey -keyalg rsa -keysize 2048 -validity 730 -alias dims -keystore .keystore
\ No newline at end of file
diff --git a/keys/key.bat b/keys/key.bat
new file mode 100644
index 0000000..3685550
--- /dev/null
+++ b/keys/key.bat
@@ -0,0 +1,5 @@
+SET PATH=C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin;%PATH%
+DEL /F selfcert.*
+makecert -sky exchange -r -n "CN=Davanum Srinivas" -b 01/01/2000 -e 01/01/2099 -sv selfcert.pvk selfcert.cer
+cert2spc selfcert.cer selfcert.spc
+pvkimprt -PFX selfcert.spc selfcert.pvk
\ No newline at end of file
diff --git a/keys/keystore.p12 b/keys/keystore.p12
new file mode 100644
index 0000000..7aad86f
--- /dev/null
+++ b/keys/keystore.p12
Binary files differ
diff --git a/keys/selfcert.pfx b/keys/selfcert.pfx
new file mode 100644
index 0000000..8b7d5ce
--- /dev/null
+++ b/keys/selfcert.pfx
Binary files differ
diff --git a/keys/signConvertImportCert.sh b/keys/signConvertImportCert.sh
new file mode 100644
index 0000000..a9f50fe
--- /dev/null
+++ b/keys/signConvertImportCert.sh
@@ -0,0 +1,17 @@
+# Sign the server certificate request with the CA using the command 

+# (again, "security" is the PEM pass phrase):

+openssl ca -config ca.config -policy policy_anything -days 730 -out cert.pem -infiles cert.req

+openssl ca -config ca.config -policy policy_anything -days 730 -out certDSA.pem -infiles certDSA.req

+

+# Convert the server certificate from PEM (plain text format) to DER (binary) format:

+# openssl x509 -outform DER -in CA.pem -out CA.crt

+openssl x509 -outform DER -in cert.pem -out cert.crt

+openssl x509 -outform DER -in certDSA.pem -out certDSA.crt

+

+# import the CA and server certificate into wss4j's keystore (note that 

+# importing the server certificate results in the keystore's wss4j 

+# certificate being updated with the new signature):

+# "$JAVA_HOME/bin/keytool" -import -file ca.crt -keystore wss4j.keystore

+"$JAVA_HOME/bin/keytool" -import -alias wss4jCert -file cert.crt -keystore wss4j.keystore

+"$JAVA_HOME/bin/keytool" -import -alias wss4jCertDSA -file certDSA.crt -keystore wss4j.keystore

+

diff --git a/keys/wss4j.keystore b/keys/wss4j.keystore
new file mode 100644
index 0000000..0d3e167
--- /dev/null
+++ b/keys/wss4j.keystore
Binary files differ
diff --git a/keys/x509.PFX.MSFT b/keys/x509.PFX.MSFT
new file mode 100644
index 0000000..98be0df
--- /dev/null
+++ b/keys/x509.PFX.MSFT
Binary files differ
diff --git a/keys/x509.keystore.SUN b/keys/x509.keystore.SUN
new file mode 100644
index 0000000..318ca8b
--- /dev/null
+++ b/keys/x509.keystore.SUN
Binary files differ
diff --git a/keys/x509.txt.BC b/keys/x509.txt.BC
new file mode 100644
index 0000000..91de954
--- /dev/null
+++ b/keys/x509.txt.BC
@@ -0,0 +1,38 @@
+-----BEGIN CERTIFICATE-----
+MIIDxDCCAy2gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBozELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBlNoYXJvbjEcMBoGA1UE
+ChMTQ29tcHV0ZXIgQXNzb2NpYXRlczEPMA0GA1UECxMGY2EuY29tMRowGAYDVQQD
+FBFwb3N0bWFzdGVyQGNhLmNvbTEgMB4GCSqGSIb3DQEJARYRcG9zdG1hc3RlckBj
+YS5jb20wHhcNMDMwNTA1MjMxNTQzWhcNMDQwNTA0MjMxNTQzWjCBozELMAkGA1UE
+BhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBlNoYXJvbjEc
+MBoGA1UEChMTQ29tcHV0ZXIgQXNzb2NpYXRlczEPMA0GA1UECxMGY2EuY29tMRow
+GAYDVQQDFBFwb3N0bWFzdGVyQGNhLmNvbTEgMB4GCSqGSIb3DQEJARYRcG9zdG1h
+c3RlckBjYS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKkewCBrpOAI
+a0ZZD4SJgTGcqQHoadt8G0WvgVxQhio5A1vSHlsA9JJP6DlsGDBw3IInNWwRI6mv
+uZ++dfB2+q8Uo8CuHaqd23jMH3LQl4VRdWF6PG4KO1FvYlMkOsBJb1CXoNzbBX33
+d2/C6aTW7Tlrg+sFfGL5CQ6smTVIC0QtAgMBAAGjggEEMIIBADAdBgNVHQ4EFgQU
+zsX+6j5MER9d6WIRNmi7s0KbfGcwgdAGA1UdIwSByDCBxYAUzsX+6j5MER9d6WIR
+Nmi7s0KbfGehgamkgaYwgaMxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNo
+dXNldHRzMQ8wDQYDVQQHEwZTaGFyb24xHDAaBgNVBAoTE0NvbXB1dGVyIEFzc29j
+aWF0ZXMxDzANBgNVBAsTBmNhLmNvbTEaMBgGA1UEAxQRcG9zdG1hc3RlckBjYS5j
+b20xIDAeBgkqhkiG9w0BCQEWEXBvc3RtYXN0ZXJAY2EuY29tggEAMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAAKSjYoFyNclkuVMUk17QAUOijXEDwXOL
+xGVVXzRs8fPnskSYOTfZ1j03Kjlf9UIXY20QD74aNfeYOZxLk72NXnXeyjkzJFWD
+Qxrvzlhu093ZC83TAAIwLM0ZRj3ru+BmGpz5JheODWMhOHlUQhi7c/RKflIaXBjY
+JPRT6IUCi7w=
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCpHsAga6TgCGtGWQ+EiYExnKkB6GnbfBtFr4FcUIYqOQNb0h5b
+APSST+g5bBgwcNyCJzVsESOpr7mfvnXwdvqvFKPArh2qndt4zB9y0JeFUXVhejxu
+CjtRb2JTJDrASW9Ql6Dc2wV993dvwumk1u05a4PrBXxi+QkOrJk1SAtELQIDAQAB
+AoGAU53rmlv+mfIvsAmKvZoK8Y+mlFXoOOfkyBCdYhpCK5Ai0/xQm+geBFVT2UhT
+sWer7wIZzMOwoU5L9eqCf5EkIiw9aGzlu4N3HJcJhTtNOTFe6G2PMBP0SdPuYEpd
+w7bOWkbMNtAqYTRoNyrXGdJjPpVccFhotunxDRsaYouOEPUCQQDgDiWKt4mvyhSG
+1OUPJ2pSvkuIG4cCOBmu89JEfy/z02T+uoRj45EpTl5QrUgQzpay0xMhzISgVjq8
+d76yP4QXAkEAwTuC5anE/YAl/WVRihVZNO15cOky6h06W2wPdtpiDoEGvgErvNRI
+qoii0KcPtWLJHPS2AV5jWqqCHoK8q8UwWwJAIjRmrM+qOGj8Sz0zHuYgiDM+6q9x
+I/iWiyvz3LsiAfIyx+SHk4xJO+oX4e8iQlaXkQNCN3W2hZfEbcNGHIYvzwJBAKw/
+lGuNbmBbP4ImMw1YAnE/zyVre0teSor8RLy55vbu5UeyW36z7SK3Mgu1IDecm5II
+QcXukbpcjCkOeYjU+kkCQQDa966ynJGTkdg+ObsoPilztiwqDEZRwEAfkmXt4Edq
+2C7EEyQptJYhG9UFJqVggsP9Yq5MLcynKkKF0YGWDVXM
+-----END RSA PRIVATE KEY-----
diff --git a/legal/LICENSE.axis b/legal/LICENSE.axis
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/legal/LICENSE.axis
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/legal/LICENSE.bouncycastle b/legal/LICENSE.bouncycastle
new file mode 100644
index 0000000..cbef4fc
--- /dev/null
+++ b/legal/LICENSE.bouncycastle
@@ -0,0 +1,7 @@
+Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
diff --git a/legal/LICENSE.commons-codec b/legal/LICENSE.commons-codec
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/legal/LICENSE.commons-codec
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/legal/LICENSE.commons-discovery b/legal/LICENSE.commons-discovery
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/legal/LICENSE.commons-discovery
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/legal/LICENSE.commons-logging b/legal/LICENSE.commons-logging
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/legal/LICENSE.commons-logging
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/legal/LICENSE.globus b/legal/LICENSE.globus
new file mode 100644
index 0000000..1934965
--- /dev/null
+++ b/legal/LICENSE.globus
@@ -0,0 +1,97 @@
+Globus Toolkit Public License (GTPL) Version 2
+
+Globus Toolkit Public License
+Version 2, July 31, 2003
+
+Copyright 1999-2003 University of Chicago and The University of Southern
+California.  All rights reserved.
+
+This software referred to as the Globus Toolkit software
+("Software") includes voluntary contributions made to the Globus
+Project collaboration.  Persons and entities that have made voluntary
+contributions are hereinafter referred to as "Contributors." This Globus
+Toolkit Public License is referred to herein as "the GTPL."  For more
+information on the Globus Project, please see http://www.globus.org/.
+
+Permission is granted for the installation, use, reproduction,
+modification, display, performance and redistribution of this Software,
+with or without modification, in source and binary forms.  Permission is
+granted for the installation, use, reproduction, modification, display,
+performance and redistribution of user files, manuals, and training and
+demonstration slides ("Documentation") distributed with or specifically
+designated as distributed under the GTPL.  Any exercise of rights under
+the GTPL is subject to the following conditions:
+
+1.  Redistributions of this Software, with or without modification,
+    must reproduce the GTPL in: (1) the Software, or (2) the Documentation
+    or some other similar material which is provided with the Software
+    (if any).
+
+2.  The Documentation, alone or if included with a redistribution of
+    the Software, must include the following notice: "This
+    product includes material developed by the Globus Project
+    (http://www.globus.org/)."
+
+    Alternatively, if that is where third-party acknowledgments normally
+    appear, this acknowledgment must be reproduced in the Software itself.
+
+3.  Globus Toolkit and Globus Project are trademarks of the
+    University of Chicago.  Any trademarks of the University of
+    Chicago or the University of Southern California may not be used
+    to endorse or promote software, or products derived therefrom, and
+    except as expressly provided herein may not be affixed to modified
+    redistributions of this Software or Documentation except with prior
+    written approval, obtainable at the discretion of the trademark
+    owner from info@globus.org.
+
+4.  To the extent that patent claims licensable by the University of
+    Southern California and/or by the University of Chicago (as Operator
+    of Argonne National Laboratory) are necessarily infringed by the
+    use or sale of the Software, you and your transferees are granted
+    a non-exclusive, worldwide, royalty-free license under such patent
+    claims, with the rights to make, use, sell, offer to sell, import and
+    otherwise transfer the Software in source code and object code form.
+    This patent license shall not apply to Documentation or to any other
+    software combinations which include the Software.  No hardware per
+    se is licensed hereunder.
+
+    If you or any subsequent transferee (a "Recipient") institutes patent
+    litigation against any entity (including a cross-claim or counterclaim
+    in a lawsuit) alleging that the Software infringes such Recipient's
+    patent(s), then such Recipient's rights granted under the patent
+    license above shall terminate as of the date such litigation is filed.
+
+5.  DISCLAIMER 
+
+    SOFTWARE AND DOCUMENTATION ARE PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+    BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+    OF SATISFACTORY QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE OR
+    USE ARE DISCLAIMED.  THE COPYRIGHT HOLDERS AND CONTRIBUTORS MAKE
+    NO REPRESENTATION THAT THE SOFTWARE, DOCUMENTATION, MODIFICATIONS,
+    ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+    PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY RIGHT.
+
+6.  LIMITATION OF LIABILITY
+
+    THE COPYRIGHT HOLDERS AND CONTRIBUTORS SHALL HAVE NO LIABILITY TO
+    LICENSEE OR OTHER PERSONS FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+    CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES OF ANY CHARACTER
+    INCLUDING, WITHOUT LIMITATION, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES, LOSS OF USE, DATA OR PROFITS, OR BUSINESS INTERRUPTION,
+    HOWEVER CAUSED AND ON ANY THEORY OF CONTRACT, WARRANTY, TORT
+    (INCLUDING NEGLIGENCE), PRODUCT LIABILITY OR OTHERWISE, ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE OR DOCUMENTATION, EVEN IF
+    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7.  The Globus Project may publish revised and/or new versions of
+    the GTPL from time to time.  Each version will be given a
+    distinguishing version number.  Once Software or Documentation
+    has been published under a particular version of the GTPL, you may
+    always continue to use it under the terms of that version. You may
+    also choose to use such Software or Documentation under the terms of
+    any subsequent version of the GTPL published by the Globus Project.
+    No one other than the Globus Project has the right to modify the
+    terms of the GTPL.
+
+Globus Toolkit Public License 7-31-03
diff --git a/legal/LICENSE.jaf b/legal/LICENSE.jaf
new file mode 100644
index 0000000..bb4fb49
--- /dev/null
+++ b/legal/LICENSE.jaf
@@ -0,0 +1,173 @@
+                           Sun Microsystems, Inc.
+                        Binary Code License Agreement
+
+READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE TERMS
+(COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE MEDIA
+PACKAGE.  BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE TERMS OF
+THIS AGREEMENT.  IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, INDICATE
+YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT THE END
+OF THIS AGREEMENT.  IF YOU DO NOT AGREE TO ALL THESE TERMS, PROMPTLY RETURN
+THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND OR, IF THE
+SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON AT THE END
+OF THIS AGREEMENT.
+
+1.  LICENSE TO USE.  Sun grants you a non-exclusive and non-transferable
+license for the internal use only of the accompanying software and
+documentation and any error corrections provided by Sun (collectively
+"Software"), by the number of users and the class of computer hardware for
+which the corresponding fee has been paid.
+
+2.  RESTRICTIONS.  Software is confidential and copyrighted. Title to
+Software and all associated intellectual property rights is retained by Sun
+and/or its licensors.  Except as specifically authorized in any Supplemental
+License Terms, you may not make copies of Software, other than a single copy
+of Software for archival purposes.  Unless enforcement is prohibited by
+applicable law, you may not modify, decompile, or reverse engineer
+Software.  You acknowledge that Software is not designed, licensed or
+intended for use in the design, construction, operation or maintenance of
+any nuclear facility.  Sun disclaims any express or implied warranty of
+fitness for such uses.  No right, title or interest in or to any trademark,
+service mark, logo or trade name of Sun or its licensors is granted under
+this Agreement.
+
+3. LIMITED WARRANTY.  Sun warrants to you that for a period of ninety (90)
+days from the date of purchase, as evidenced by a copy of the receipt, the
+media on which Software is furnished (if any) will be free of defects in
+materials and workmanship under normal use.  Except for the foregoing,
+Software is provided "AS IS".  Your exclusive remedy and Sun's entire
+liability under this limited warranty will be at Sun's option to replace
+Software media or refund the fee paid for Software.
+
+4.  DISCLAIMER OF WARRANTY.  UNLESS SPECIFIED IN THIS AGREEMENT, ALL EXPRESS
+OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED
+WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE DISCLAIMERS
+ARE HELD TO BE LEGALLY INVALID.
+
+5.  LIMITATION OF LIABILITY.  TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR
+DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT
+OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  In no event will Sun's
+liability to you, whether in contract, tort (including negligence), or
+otherwise, exceed the amount paid by you for Software under this Agreement.
+The foregoing limitations will apply even if the above stated warranty fails
+of its essential purpose.
+
+6.  Termination.  This Agreement is effective until terminated.  You may
+terminate this Agreement at any time by destroying all copies of Software.
+This Agreement will terminate immediately without notice from Sun if you
+fail to comply with any provision of this Agreement.  Upon Termination, you
+must destroy all copies of Software.
+
+7. Export Regulations. All Software and technical data delivered under this
+Agreement are subject to US export control laws and may be subject to export
+or import regulations in other countries.  You agree to comply strictly with
+all such laws and regulations and acknowledge that you have the
+responsibility to obtain such licenses to export, re-export, or import as
+may be required after delivery to you.
+
+8.   U.S. Government Restricted Rights.  If Software is being acquired by or
+on behalf of the U.S. Government or by a U.S. Government prime contractor or
+subcontractor (at any tier), then the Government's rights in Software and
+accompanying documentation will be only as set forth in this Agreement; this
+is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of
+Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD
+acquisitions).
+
+9.  Governing Law.  Any action related to this Agreement will be governed by
+California law and controlling U.S. federal law.  No choice of law rules of
+any jurisdiction will apply.
+
+10.  Severability. If any provision of this Agreement is held to be
+unenforceable, this Agreement will remain in effect with the provision
+omitted, unless omission would frustrate the intent of the parties, in which
+case this Agreement will immediately terminate.
+
+11.  Integration.  This Agreement is the entire agreement between you and
+Sun relating to its subject matter.  It supersedes all prior or
+contemporaneous oral or written communications, proposals, representations
+and warranties and prevails over any conflicting or additional terms of any
+quote, order, acknowledgment, or other communication between the parties
+relating to its subject matter during the term of this Agreement.  No
+modification of this Agreement will be binding, unless in writing and signed
+by an authorized representative of each party.
+
+                           JAVA OPTIONAL PACKAGE
+
+              JAVABEANS(TM) ACTIVATION FRAMEWORK, VERSION 1.0.2
+                         SUPPLEMENTAL LICENSE TERMS
+
+These supplemental license terms ("Supplemental Terms") add to or modify the
+terms of the Binary Code License Agreement (collectively, the "Agreement").
+Capitalized terms not defined in these Supplemental Terms shall have the
+same meanings ascribed to them in the Agreement. These Supplemental Terms
+shall supersede any inconsistent or conflicting terms in the Agreement, or
+in any license contained within the Software.
+
+1. Software Internal Use and Development License Grant.  Subject to the
+terms and conditions of this Agreement, including, but not limited to
+Section 3 (Java(TM) Technology Restrictions) of these Supplemental Terms,
+Sun grants you a non-exclusive, non-transferable, limited license to
+reproduce internally and use internally the binary form of the Software,
+complete and unmodified, for the sole purpose of designing, developing and
+testing your Java applets and applications ("Programs").
+
+2. License to Distribute Software.  In addition to the license granted in
+Section 1 (Software Internal Use and Development License Grant) of these
+Supplemental Terms, subject to the terms and conditions of this Agreement,
+including but not limited to, Section 3 (Java Technology Restrictions) of
+these Supplemental Terms, Sun grants you a non-exclusive, non-transferable,
+limited license to reproduce and distribute the Software in binary code form
+only, provided that you (i) distribute the Software complete and unmodified
+and only bundled as part of your Programs, (ii) do not distribute additional
+software intended to replace any component(s) of the Software, (iii) do not
+remove or alter any proprietary legends or notices contained in the
+Software, (iv) only distribute the Software subject to a license agreement
+that protects Sun's interests consistent with the terms contained in this
+Agreement, and (v) agree to defend and indemnify Sun and its licensors from
+and against any damages, costs, liabilities, settlement amounts and/or
+expenses (including attorneys' fees) incurred in connection with any claim,
+lawsuit or action by any third party that arises or results from the use or
+distribution of any and all Programs and/or Software.
+
+3. Java Technology Restrictions. You may not modify the Java Platform
+Interface ("JPI", identified as classes contained within the "java" package
+or any subpackages of the "java" package), by creating additional classes
+within the JPI or otherwise causing the addition to or modification of the
+classes in the JPI.  In the event that you create an additional class and
+associated API(s) which (i) extends the functionality of the Java platform,
+and (ii) is exposed to third party software developers for the purpose of
+developing additional software which invokes such additional API, you must
+promptly publish broadly an accurate specification for such API for free use
+by all developers.  You may not create, or authorize your licensees to
+create additional classes, interfaces, or subpackages that are in any way
+identified as "java", "javax", "sun" or similar convention as specified by
+Sun in any naming convention designation.
+
+4. No Support. Sun is under no obligation to support the Software or to
+provide you with updates or error corrections. You acknowledge that the
+Software may have defects or deficiencies which cannot or will not be
+corrected by Sun.
+
+5. Trademarks and Logos. You acknowledge and agree as between you and Sun
+that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, and iPLANET trademarks
+and all SUN, SOLARIS, JAVA, JINI, FORTE, and iPLANET-related trademarks,
+service marks, logos and other brand designations ("Sun Marks"), and you
+agree to comply with the Sun Trademark and Logo Usage Requirements currently
+located at http://www.sun.com/policies/trademarks. Any use you make of the
+Sun Marks inures to Sun's benefit.
+
+6. Source Code. Software may contain source code that is provided solely for
+reference purposes pursuant to the terms of this Agreement.  Source code may
+not be redistributed unless expressly provided for in this Agreement.
+
+7. Termination for Infringement.  Either party may terminate this Agreement
+immediately should any Software become, or in either party's opinion be
+likely to become, the subject of a claim of infringement of any intellectual
+property right.
+
+For inquiries please contact: Sun Microsystems, Inc.  901 San Antonio Road,
+Palo Alto, California 94303
+(LFI#115020/Form ID#011801)
diff --git a/legal/LICENSE.javamail b/legal/LICENSE.javamail
new file mode 100644
index 0000000..2173c8c
--- /dev/null
+++ b/legal/LICENSE.javamail
@@ -0,0 +1,170 @@
+                          Sun Microsystems, Inc.
+                       Binary Code License Agreement
+
+READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE
+TERMS (COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE
+MEDIA PACKAGE.  BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE
+TERMS OF THIS AGREEMENT.  IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY,
+INDICATE YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT
+THE END OF THIS AGREEMENT.  IF YOU DO NOT AGREE TO ALL THESE TERMS,
+PROMPTLY RETURN THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND
+OR, IF THE SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON
+AT THE END OF THIS AGREEMENT.
+
+1.  LICENSE TO USE.  Sun grants you a non-exclusive and non-transferable
+license for the internal use only of the accompanying software and
+documentation and any error corrections provided by Sun (collectively
+"Software"), by the number of users and the class of computer hardware for
+which the corresponding fee has been paid.
+
+2.  RESTRICTIONS.  Software is confidential and copyrighted. Title to
+Software and all associated intellectual property rights is retained by Sun
+and/or its licensors.  Except as specifically authorized in any
+Supplemental License Terms, you may not make copies of Software, other than
+a single copy of Software for archival purposes.  Unless enforcement is
+prohibited by applicable law, you may not modify, decompile, or reverse
+engineer Software.  You acknowledge that Software is not designed, licensed
+or intended for use in the design, construction, operation or maintenance
+of any nuclear facility.  Sun disclaims any express or implied warranty of
+fitness for such uses.  No right, title or interest in or to any trademark,
+service mark, logo or trade name of Sun or its licensors is granted under
+this Agreement.
+
+3. LIMITED WARRANTY.  Sun warrants to you that for a period of ninety (90)
+days from the date of purchase, as evidenced by a copy of the receipt, the
+media on which Software is furnished (if any) will be free of defects in
+materials and workmanship under normal use.  Except for the foregoing,
+Software is provided "AS IS".  Your exclusive remedy and Sun's entire
+liability under this limited warranty will be at Sun's option to replace
+Software media or refund the fee paid for Software.
+
+4.  DISCLAIMER OF WARRANTY.  UNLESS SPECIFIED IN THIS AGREEMENT, ALL
+EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+OR NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE
+DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
+
+5.  LIMITATION OF LIABILITY.  TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR
+DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT
+OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  In no event will Sun's
+liability to you, whether in contract, tort (including negligence), or
+otherwise, exceed the amount paid by you for Software under this
+Agreement.  The foregoing limitations will apply even if the above stated
+warranty fails of its essential purpose.
+
+6.  Termination.  This Agreement is effective until terminated.  You may
+terminate this Agreement at any time by destroying all copies of Software.
+This Agreement will terminate immediately without notice from Sun if you
+fail to comply with any provision of this Agreement.  Upon Termination, you
+must destroy all copies of Software.
+
+7. Export Regulations. All Software and technical data delivered under this
+Agreement are subject to US export control laws and may be subject to
+export or import regulations in other countries.  You agree to comply
+strictly with all such laws and regulations and acknowledge that you have
+the responsibility to obtain such licenses to export, re-export, or import
+as may be required after delivery to you.
+
+8.   U.S. Government Restricted Rights.  If Software is being acquired by
+or on behalf of the U.S. Government or by a U.S. Government prime
+contractor or subcontractor (at any tier), then the Government's rights in
+Software and accompanying documentation will be only as set forth in this
+Agreement; this is in accordance with 48 CFR 227.7201 through 227.7202-4
+(for Department of Defense (DOD) acquisitions) and with 48 CFR 2.101 and
+12.212 (for non-DOD acquisitions).
+
+9.  Governing Law.  Any action related to this Agreement will be governed
+by California law and controlling U.S. federal law.  No choice of law rules
+of any jurisdiction will apply.
+
+10.  Severability. If any provision of this Agreement is held to be
+unenforceable, this Agreement will remain in effect with the provision
+omitted, unless omission would frustrate the intent of the parties, in
+which case this Agreement will immediately terminate.
+
+11.  Integration.  This Agreement is the entire agreement between you and
+Sun relating to its subject matter.  It supersedes all prior or
+contemporaneous oral or written communications, proposals, representations
+and warranties and prevails over any conflicting or additional terms of any
+quote, order, acknowledgment, or other communication between the parties
+relating to its subject matter during the term of this Agreement.  No
+modification of this Agreement will be binding, unless in writing and
+signed by an authorized representative of each party.
+
+
+                           JAVAMAIL, VERSION 1.3
+                         SUPPLEMENTAL LICENSE TERMS
+
+These supplemental license terms ("Supplemental Terms") add to or modify
+the terms of the Binary Code License Agreement (collectively, the
+"Agreement"). Capitalized terms not defined in these Supplemental Terms
+shall have the same meanings ascribed to them in the Agreement. These
+Supplemental Terms shall supersede any inconsistent or conflicting terms in
+the Agreement, or in any license contained within the Software.
+
+1. Software Internal Use and Development License Grant.  Subject to the
+terms and conditions of this Agreement, including, but not limited to
+Section 3 (Java(TM) Technology Restrictions) of these Supplemental Terms,
+Sun grants you a non-exclusive, non-transferable, limited license to
+reproduce internally and use internally the binary form of the Software,
+complete and unmodified, for the sole purpose of designing, developing and
+testing your Java applets and applications ("Programs").
+
+2. License to Distribute Software. Subject to the terms and conditions of
+this Agreement, including, but not limited to Section 3 (Java (TM)
+Technology Restrictions) of these Supplemental Terms, Sun grants you a
+non-exclusive, non-transferable, limited license to reproduce and
+distribute the Software in binary code form only, provided that (i) you
+distribute the Software complete and unmodified and only bundled as part
+of, and for the sole purpose of  running, your Java applets or applications
+("Programs"), (ii) the Programs add significant and primary functionality
+to the Software, (iii) you do not distribute additional software intended
+to replace any component(s) of the Software, (iv) you do not remove or
+alter any proprietary legends or notices contained in the Software, (v) you
+only distribute the Software subject to a license agreement that protects
+Sun's interests consistent with the terms contained in this Agreement, and
+(vi) you agree to defend and indemnify Sun and its licensors from and
+against any damages, costs, liabilities, settlement amounts and/or expenses
+(including attorneys' fees) incurred in connection with any claim, lawsuit
+or action by any third party that arises or results from the use or
+distribution of any and all Programs and/or Software.
+
+3. Java Technology Restrictions. You may not modify the Java Platform
+Interface ("JPI", identified as classes contained within the "java" package
+or any subpackages of the "java" package), by creating additional classes
+within the JPI or otherwise causing the addition to or modification of the
+classes in the JPI.  In the event that you create an additional class and
+associated API(s) which (i) extends the functionality of the Java platform,
+and (ii) is exposed to third party software developers for the purpose of
+developing additional software which invokes such additional API, you must
+promptly publish broadly an accurate specification for such API for free
+use by all developers.  You may not create, or authorize your licensees to
+create additional classes, interfaces, or subpackages that are in any way
+identified as "java", "javax", "sun" or similar convention as specified by
+Sun in any naming convention designation.
+
+4. Trademarks and Logos. You acknowledge and agree as between you and Sun
+that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL
+and iPLANET trademarks and all SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE,
+STARPORTAL and iPLANET-related trademarks, service marks, logos and other
+brand designations ("Sun Marks"), and you agree to comply with the Sun
+Trademark and Logo Usage Requirements currently located at
+http://www.sun.com/policies/trademarks. Any use you make of the Sun Marks
+inures to Sun's benefit.
+
+5. Source Code. Software may contain source code that is provided solely
+for reference purposes pursuant to the terms of this Agreement.  Source
+code may not be redistributed unless expressly provided for in this
+Agreement.
+
+6. Termination for Infringement.  Either party may terminate this Agreement
+immediately should any Software become, or in either party's opinion be
+likely to become, the subject of a claim of infringement of any
+intellectual property right.
+
+For inquiries please contact: Sun Microsystems, Inc., 4150 Network Circle,
+Santa Clara, California 95054, U.S.A
+(LFI#114176/Form ID#011801)
diff --git a/legal/LICENSE.junit b/legal/LICENSE.junit
new file mode 100644
index 0000000..fbd1e20
--- /dev/null
+++ b/legal/LICENSE.junit
@@ -0,0 +1,185 @@
+
+IBM Public License Version 1.0 
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS IBM PUBLIC 
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE 
+PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 
+1. DEFINITIONS 
+
+"Contribution" means: 
+  a) in the case of International Business Machines Corporation ("IBM"), 
+  the Original Program, and 
+  b) in the case of each Contributor, 
+  i) changes to the Program, and
+  ii) additions to the Program;
+  where such changes and/or additions to the Program originate from and 
+  are distributed by that particular Contributor. A Contribution 
+  'originates' from a Contributor if it was added to the Program by such 
+  Contributor itself or anyone acting on such Contributor's behalf. 
+  Contributions do not include additions to the Program which: (i) are 
+  separate modules of software distributed in conjunction with the Program 
+  under their own license agreement, and (ii) are not derivative works of 
+  the Program.
+"Contributor" means IBM and any other entity that distributes the Program. 
+
+"Licensed Patents " mean patent claims licensable by a Contributor which 
+are necessarily infringed by the use or sale of its Contribution alone or 
+when combined with the Program. 
+"Original Program" means the original version of the software accompanying 
+this Agreement as released by IBM, including source code, object code and 
+documentation, if any. 
+"Program" means the Original Program and Contributions. 
+"Recipient" means anyone who receives the Program under this Agreement, 
+including all Contributors. 
+2. GRANT OF RIGHTS 
+  a) Subject to the terms of this Agreement, each Contributor hereby 
+  grants Recipient a non-exclusive, worldwide, royalty-free copyright 
+  license to reproduce, prepare derivative works of, publicly display, 
+  publicly perform, distribute and sublicense the Contribution of such 
+  Contributor, if any, and such derivative works, in source code and 
+  object code form.
+  b) Subject to the terms of this Agreement, each Contributor hereby 
+  grants Recipient a non-exclusive, worldwide, royalty-free patent license 
+  under Licensed Patents to make, use, sell, offer to sell, import and 
+  otherwise transfer the Contribution of such Contributor, if any, in 
+  source code and object code form. This patent license shall apply to the 
+  combination of the Contribution and the Program if, at the time the 
+  Contribution is added by the Contributor, such addition of the 
+  Contribution causes such combination to be covered by the Licensed 
+  Patents. The patent license shall not apply to any other combinations 
+  which include the Contribution. No hardware per se is licensed 
+  hereunder. 
+  c) Recipient understands that although each Contributor grants the 
+  licenses to its Contributions set forth herein, no assurances are 
+  provided by any Contributor that the Program does not infringe the 
+  patent or other intellectual property rights of any other entity. Each 
+  Contributor disclaims any liability to Recipient for claims brought by 
+  any other entity based on infringement of intellectual property rights 
+  or otherwise. As a condition to exercising the rights and licenses 
+  granted hereunder, each Recipient hereby assumes sole responsibility to 
+  secure any other intellectual property rights needed, if any. For 
+  example, if a third party patent license is required to allow Recipient 
+  to distribute the Program, it is Recipient's responsibility to acquire 
+  that license before distributing the Program.
+  d) Each Contributor represents that to its knowledge it has sufficient 
+  copyright rights in its Contribution, if any, to grant the copyright 
+  license set forth in this Agreement. 
+3. REQUIREMENTS 
+A Contributor may choose to distribute the Program in object code form 
+under its own license agreement, provided that: 
+  a) it complies with the terms and conditions of this Agreement; and
+  b) its license agreement:
+  i) effectively disclaims on behalf of all Contributors all warranties 
+  and conditions, express and implied, including warranties or conditions 
+  of title and non-infringement, and implied warranties or conditions of 
+  merchantability and fitness for a particular purpose; 
+  ii) effectively excludes on behalf of all Contributors all liability for 
+  damages, including direct, indirect, special, incidental and 
+  consequential damages, such as lost profits; 
+  iii) states that any provisions which differ from this Agreement are 
+  offered by that Contributor alone and not by any other party; and
+  iv) states that source code for the Program is available from such 
+  Contributor, and informs licensees how to obtain it in a reasonable 
+  manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form: 
+  a) it must be made available under this Agreement; and 
+  b) a copy of this Agreement must be included with each copy of the 
+  Program. 
+Each Contributor must include the following in a conspicuous location in 
+the Program: 
+  Copyright © {date here}, International Business Machines Corporation and 
+  others. All Rights Reserved. 
+In addition, each Contributor must identify itself as the originator of 
+its Contribution, if any, in a manner that reasonably allows subsequent 
+Recipients to identify the originator of the Contribution. 
+4. COMMERCIAL DISTRIBUTION 
+Commercial distributors of software may accept certain responsibilities 
+with respect to end users, business partners and the like. While this 
+license is intended to facilitate the commercial use of the Program, the 
+Contributor who includes the Program in a commercial product offering 
+should do so in a manner which does not create potential liability for 
+other Contributors. Therefore, if a Contributor includes the Program in a 
+commercial product offering, such Contributor ("Commercial Contributor") 
+hereby agrees to defend and indemnify every other Contributor 
+("Indemnified Contributor") against any losses, damages and costs 
+(collectively "Losses") arising from claims, lawsuits and other legal 
+actions brought by a third party against the Indemnified Contributor to 
+the extent caused by the acts or omissions of such Commercial Contributor 
+in connection with its distribution of the Program in a commercial product 
+offering. The obligations in this section do not apply to any claims or 
+Losses relating to any actual or alleged intellectual property 
+infringement. In order to qualify, an Indemnified Contributor must: a) 
+promptly notify the Commercial Contributor in writing of such claim, and 
+b) allow the Commercial Contributor to control, and cooperate with the 
+Commercial Contributor in, the defense and any related settlement 
+negotiations. The Indemnified Contributor may participate in any such 
+claim at its own expense. 
+For example, a Contributor might include the Program in a commercial 
+product offering, Product X. That Contributor is then a Commercial 
+Contributor. If that Commercial Contributor then makes performance claims, 
+or offers warranties related to Product X, those performance claims and 
+warranties are such Commercial Contributor's responsibility alone. Under 
+this section, the Commercial Contributor would have to defend claims 
+against the other Contributors related to those performance claims and 
+warranties, and if a court requires any other Contributor to pay any 
+damages as a result, the Commercial Contributor must pay those damages. 
+5. NO WARRANTY 
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 
+EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 
+CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 
+PARTICULAR PURPOSE. Each Recipient is solely responsible for determining 
+the appropriateness of using and distributing the Program and assumes all 
+risks associated with its exercise of rights under this Agreement, 
+including but not limited to the risks and costs of program errors, 
+compliance with applicable laws, damage to or loss of data, programs or 
+equipment, and unavailability or interruption of operations. 
+6. DISCLAIMER OF LIABILITY 
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING 
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION 
+OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF 
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+7. GENERAL 
+If any provision of this Agreement is invalid or unenforceable under 
+applicable law, it shall not affect the validity or enforceability of the 
+remainder of the terms of this Agreement, and without further action by 
+the parties hereto, such provision shall be reformed to the minimum extent 
+necessary to make such provision valid and enforceable. 
+If Recipient institutes patent litigation against a Contributor with 
+respect to a patent applicable to software (including a cross-claim or 
+counterclaim in a lawsuit), then any patent licenses granted by that 
+Contributor to such Recipient under this Agreement shall terminate as of 
+the date such litigation is filed. In addition, If Recipient institutes 
+patent litigation against any entity (including a cross-claim or 
+counterclaim in a lawsuit) alleging that the Program itself (excluding 
+combinations of the Program with other software or hardware) infringes 
+such Recipient's patent(s), then such Recipient's rights granted under 
+Section 2(b) shall terminate as of the date such litigation is filed. 
+All Recipient's rights under this Agreement shall terminate if it fails to 
+comply with any of the material terms or conditions of this Agreement and 
+does not cure such failure in a reasonable period of time after becoming 
+aware of such noncompliance. If all Recipient's rights under this 
+Agreement terminate, Recipient agrees to cease use and distribution of the 
+Program as soon as reasonably practicable. However, Recipient's 
+obligations under this Agreement and any licenses granted by Recipient 
+relating to the Program shall continue and survive. 
+IBM may publish new versions (including revisions) of this Agreement from 
+time to time. Each new version of the Agreement will be given a 
+distinguishing version number. The Program (including Contributions) may 
+always be distributed subject to the version of the Agreement under which 
+it was received. In addition, after a new version of the Agreement is 
+published, Contributor may elect to distribute the Program (including its 
+Contributions) under the new version. No one other than IBM has the right 
+to modify this Agreement. Except as expressly stated in Sections 2(a) and 
+2(b) above, Recipient receives no rights or licenses to the intellectual 
+property of any Contributor under this Agreement, whether expressly, by 
+implication, estoppel or otherwise. All rights in the Program not 
+expressly granted under this Agreement are reserved. 
+This Agreement is governed by the laws of the State of New York and the 
+intellectual property laws of the United States of America. No party to 
+this Agreement will bring a legal action under this Agreement more than 
+one year after the cause of action arose. Each party waives its rights to 
+a jury trial in any resulting litigation. 
diff --git a/legal/LICENSE.log4j b/legal/LICENSE.log4j
new file mode 100644
index 0000000..007db57
--- /dev/null
+++ b/legal/LICENSE.log4j
@@ -0,0 +1,48 @@
+/*
+ * ============================================================================
+ *                   The Apache Software License, Version 1.1
+ * ============================================================================
+ * 
+ *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of  source code must  retain the above copyright  notice,
+ *    this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include  the following  acknowledgment:  "This product includes  software
+ *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+ *    Alternately, this  acknowledgment may  appear in the software itself,  if
+ *    and wherever such third-party acknowledgments normally appear.
+ * 
+ * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
+ *    endorse  or promote  products derived  from this  software without  prior
+ *    written permission. For written permission, please contact
+ *    apache@apache.org.
+ * 
+ * 5. Products  derived from this software may not  be called "Apache", nor may
+ *    "Apache" appear  in their name,  without prior written permission  of the
+ *    Apache Software Foundation.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * This software  consists of voluntary contributions made  by many individuals
+ * on  behalf of the Apache Software  Foundation.  For more  information on the 
+ * Apache Software Foundation, please see <http://www.apache.org/>.
+ *
+ */
diff --git a/legal/LICENSE.opensaml b/legal/LICENSE.opensaml
new file mode 100644
index 0000000..becbdf3
--- /dev/null
+++ b/legal/LICENSE.opensaml
@@ -0,0 +1,47 @@
+The OpenSAML License, Version 1. 
+Copyright (c) 2002 
+University Corporation for Advanced Internet Development, Inc. 
+All rights reserved
+
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this 
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, 
+this list of conditions and the following disclaimer in the documentation 
+and/or other materials provided with the distribution, if any, must include 
+the following acknowledgment: "This product includes software developed by 
+the University Corporation for Advanced Internet Development 
+<http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement 
+may appear in the software itself, if and wherever such third-party 
+acknowledgments normally appear.
+
+Neither the name of OpenSAML nor the names of its contributors, nor 
+Internet2, nor the University Corporation for Advanced Internet Development, 
+Inc., nor UCAID may be used to endorse or promote products derived from this 
+software without specific prior written permission. For written permission, 
+please contact opensaml@opensaml.org
+
+Products derived from this software may not be called OpenSAML, Internet2, 
+UCAID, or the University Corporation for Advanced Internet Development, nor 
+may OpenSAML appear in their name, without prior written permission of the 
+University Corporation for Advanced Internet Development.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK 
+OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. 
+IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY 
+CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/legal/LICENSE.security b/legal/LICENSE.security
new file mode 100644
index 0000000..16b47ec
--- /dev/null
+++ b/legal/LICENSE.security
@@ -0,0 +1,54 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache XML-Security" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
diff --git a/legal/LICENSE.wsdl4j b/legal/LICENSE.wsdl4j
new file mode 100644
index 0000000..709c2d4
--- /dev/null
+++ b/legal/LICENSE.wsdl4j
@@ -0,0 +1,91 @@
+Common Public License  
+ 
+ Common Public License Version 0.5 
+ 
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 
+ 
+ 
+ 1. DEFINITIONS 
+ 
+ "Contribution" means: 
+ 
+ a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and 
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+ where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+ 
+ "Contributor" means any person or entity that distributes the Program. 
+ 
+ 
+ "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. 
+ 
+ 
+ "Program" means the Contributions distributed in accordance with this Agreement. 
+ 
+ 
+ "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 
+ 
+ 
+ 2. GRANT OF RIGHTS 
+ 
+ a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+ b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+ c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+ d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 
+ 3. REQUIREMENTS 
+ 
+ A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: 
+ 
+ a) it complies with the terms and conditions of this Agreement; and
+ b) its license agreement:
+ i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; 
+ ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; 
+ iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+ iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. 
+ When the Program is made available in source code form: 
+ 
+ a) it must be made available under this Agreement; and 
+ b) a copy of this Agreement must be included with each copy of the Program. 
+ 
+ Contributors may not remove or alter any copyright notices contained within the Program. 
+ 
+ 
+ 
+ Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 
+ 
+ 
+ 4. COMMERCIAL DISTRIBUTION 
+ 
+ Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. 
+ 
+ 
+ For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 
+ 
+ 
+ 5. NO WARRANTY 
+ 
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 
+ 
+ 
+ 6. DISCLAIMER OF LIABILITY 
+ 
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+ 
+ 
+ 7. GENERAL 
+ 
+ If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 
+ 
+ 
+ If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. 
+ 
+ 
+ All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. 
+ 
+ 
+ Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. 
+ 
+ 
+ This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. 
+ 
\ No newline at end of file
diff --git a/legal/LICENSE.xalan b/legal/LICENSE.xalan
new file mode 100644
index 0000000..21156a6
--- /dev/null
+++ b/legal/LICENSE.xalan
@@ -0,0 +1,55 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
diff --git a/legal/LICENSE.xerces b/legal/LICENSE.xerces
new file mode 100644
index 0000000..b37087c
--- /dev/null
+++ b/legal/LICENSE.xerces
@@ -0,0 +1,56 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xerces" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, International
+ * Business Machines, Inc., http://www.ibm.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
diff --git a/legal/LICENSE.xml-apis b/legal/LICENSE.xml-apis
new file mode 100644
index 0000000..930145f
--- /dev/null
+++ b/legal/LICENSE.xml-apis
@@ -0,0 +1,5 @@
+
+xml-apis is covered by The Apache Software License, Version 1.1
+
+FIXME: Put license text in here once it is available at
+       http://cvs.apache.org/viewcvs.cgi/xml-commons/
diff --git a/legal/README.globus b/legal/README.globus
new file mode 100644
index 0000000..a032081
--- /dev/null
+++ b/legal/README.globus
@@ -0,0 +1,8 @@
+NOTE: On September 2, 2003, the Globus Project announced that it had
+transformed itself into the Globus Alliance. Members include Argonne
+National Laboratory, the University of Chicago, and the University of
+Southern California's Information Sciences Institute, Edinburgh
+University in Scotland (EPCC and NeSC) and the Swedish Center for
+Parallel Computers (PDC) at the Royal Institute of Technology in
+Stockholm. For more information, see
+http://www.globus.org/about/news/prGAannounce.html
\ No newline at end of file
diff --git a/lib/addressing-1.0.jar b/lib/addressing-1.0.jar
new file mode 100644
index 0000000..9cdca98
--- /dev/null
+++ b/lib/addressing-1.0.jar
Binary files differ
diff --git a/lib/axis-1.4.jar b/lib/axis-1.4.jar
new file mode 100644
index 0000000..20b09a5
--- /dev/null
+++ b/lib/axis-1.4.jar
Binary files differ
diff --git a/lib/axis-ant-1.4.jar b/lib/axis-ant-1.4.jar
new file mode 100644
index 0000000..17527ff
--- /dev/null
+++ b/lib/axis-ant-1.4.jar
Binary files differ
diff --git a/lib/axis-jaxrpc-1.4.jar b/lib/axis-jaxrpc-1.4.jar
new file mode 100644
index 0000000..a2c13d9
--- /dev/null
+++ b/lib/axis-jaxrpc-1.4.jar
Binary files differ
diff --git a/lib/axis-saaj-1.4.jar b/lib/axis-saaj-1.4.jar
new file mode 100644
index 0000000..4ea696e
--- /dev/null
+++ b/lib/axis-saaj-1.4.jar
Binary files differ
diff --git a/lib/bcprov-jdk13-132.jar b/lib/bcprov-jdk13-132.jar
new file mode 100644
index 0000000..e9226bd
--- /dev/null
+++ b/lib/bcprov-jdk13-132.jar
Binary files differ
diff --git a/lib/bcprov-jdk15-132.jar b/lib/bcprov-jdk15-132.jar
new file mode 100644
index 0000000..edcbde2
--- /dev/null
+++ b/lib/bcprov-jdk15-132.jar
Binary files differ
diff --git a/lib/commons-codec-1.3.jar b/lib/commons-codec-1.3.jar
new file mode 100644
index 0000000..957b675
--- /dev/null
+++ b/lib/commons-codec-1.3.jar
Binary files differ
diff --git a/lib/commons-discovery-0.2.jar b/lib/commons-discovery-0.2.jar
new file mode 100644
index 0000000..b885548
--- /dev/null
+++ b/lib/commons-discovery-0.2.jar
Binary files differ
diff --git a/lib/commons-httpclient-3.0-rc2.jar b/lib/commons-httpclient-3.0-rc2.jar
new file mode 100644
index 0000000..bea0a98
--- /dev/null
+++ b/lib/commons-httpclient-3.0-rc2.jar
Binary files differ
diff --git a/lib/commons-logging-1.0.4.jar b/lib/commons-logging-1.0.4.jar
new file mode 100644
index 0000000..b73a80f
--- /dev/null
+++ b/lib/commons-logging-1.0.4.jar
Binary files differ
diff --git a/lib/junit-3.8.1.jar b/lib/junit-3.8.1.jar
new file mode 100644
index 0000000..674d71e
--- /dev/null
+++ b/lib/junit-3.8.1.jar
Binary files differ
diff --git a/lib/log4j-1.2.9.jar b/lib/log4j-1.2.9.jar
new file mode 100644
index 0000000..a6568b0
--- /dev/null
+++ b/lib/log4j-1.2.9.jar
Binary files differ
diff --git a/lib/opensaml-1.0.1.jar b/lib/opensaml-1.0.1.jar
new file mode 100644
index 0000000..4402187
--- /dev/null
+++ b/lib/opensaml-1.0.1.jar
Binary files differ
diff --git a/lib/policy.jar b/lib/policy.jar
new file mode 100644
index 0000000..707770c
--- /dev/null
+++ b/lib/policy.jar
Binary files differ
diff --git a/lib/serializer-2.7.0.jar b/lib/serializer-2.7.0.jar
new file mode 100644
index 0000000..7cd8069
--- /dev/null
+++ b/lib/serializer-2.7.0.jar
Binary files differ
diff --git a/lib/wsdl4j-1.5.1.jar b/lib/wsdl4j-1.5.1.jar
new file mode 100644
index 0000000..c6254ee
--- /dev/null
+++ b/lib/wsdl4j-1.5.1.jar
Binary files differ
diff --git a/lib/xalan-2.7.0.jar b/lib/xalan-2.7.0.jar
new file mode 100644
index 0000000..979ee76
--- /dev/null
+++ b/lib/xalan-2.7.0.jar
Binary files differ
diff --git a/lib/xmlsec-1.3.0.jar b/lib/xmlsec-1.3.0.jar
new file mode 100644
index 0000000..6b69b80
--- /dev/null
+++ b/lib/xmlsec-1.3.0.jar
Binary files differ
diff --git a/maven.xml b/maven.xml
new file mode 100644
index 0000000..52374de
--- /dev/null
+++ b/maven.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- $Revision$ $Date$ -->
+
+<project default="jar"
+    xmlns:j="jelly:core"
+    xmlns:maven="jelly:maven"
+    xmlns:deploy="deploy"
+    xmlns:ant="jelly:ant">
+
+    <path id="test.classpath">
+        <path refid="maven.dependency.classpath"/>
+        <pathelement path="${maven.build.dest}"/>
+        <pathelement path="target/classes"/>
+        <pathelement path="target/test-classes"/>
+    </path>
+
+    <preGoal name="java:compile">
+        <ant:path id="classpath.libraries">
+            <ant:fileset dir="./lib">
+                <ant:include name="**/*.jar"/>
+            </ant:fileset>
+            <ant:pathelement path="${maven.build.dest}"/>
+            <ant:pathelement path="target/classes"/>
+        </ant:path>
+        <maven:addPath id="maven.dependency.classpath" refid="classpath.libraries"/>
+    </preGoal>
+
+    <preGoal name="test:compile">
+        <taskdef resource="axis-tasks.properties" classpathref="maven.dependency.classpath"/>
+
+        <property name="dir.wss4j" value="."/>
+        <property name="dir.interop" value="${dir.wss4j}/interop"/>
+        <property name="dir.interop2" value="${dir.wss4j}/test"/>
+        <property name="dir.work" value="${dir.wss4j}/target/work"/>
+        <property name="server" value="org/apache/ws/axis/oasis/ping"/>
+        <property name="client" value="org/apache/ws/axis/oasis"/>
+
+        <mkdir dir="${dir.work}"/>
+
+        <axis-wsdl2java
+            output="${dir.work}"
+            serverSide="yes"
+            testcase="no"
+            verbose="no"
+            url="${dir.interop}/ping.wsdl">
+            <mapping
+                namespace="http://xmlsoap.org/Ping"
+                package="org.apache.ws.axis.oasis.ping"/>
+        </axis-wsdl2java>
+
+        <copy todir="target/classes" overwrite="yes">
+          <fileset dir="${dir.interop}/${server}">
+            <include name="*.properties"/>
+          </fileset>
+        </copy>
+        <copy todir="${dir.work}/${server}" overwrite="yes">
+          <fileset dir="${dir.interop}/${server}">
+            <include name="*.java"/>
+            <include name="*.wsdd"/>
+          </fileset>
+        </copy>
+        <copy todir="${dir.work}/${client}" overwrite="yes">
+          <fileset dir="${dir.interop}/${client}">
+            <include name="*.java"/>
+            <include name="*.wsdd"/>
+          </fileset>
+        </copy>
+
+        <path id="wss4j.samples.set"
+              location="${basedir}/samples"/>
+        <path id="wss4j.generated.set"
+              location="${basedir}/target/work"/>
+        <maven:addPath id="maven.test.compile.src.set"
+                       refid="wss4j.samples.set"/>
+        <maven:addPath id="maven.test.compile.src.set"
+                       refid="wss4j.generated.set"/>
+    </preGoal>
+
+    <goal name="start-functional-test-http-server">
+        <ant:echo message="Starting http server."/>
+        <ant:java classname="org.apache.axis.transport.http.SimpleAxisServer" fork="true" spawn="yes" dir=".">
+            <ant:classpath refid="test.classpath"/>
+        </ant:java>
+    </goal>
+
+    <preGoal name="test:test">
+        <j:thread>
+          <attainGoal name="start-functional-test-http-server"/>
+        </j:thread>
+
+        <sleep seconds="2"/>
+
+        <path id="deploy.xml.files">
+            <fileset dir="./target/work">
+                <include name="**/deploy.wsdd"/>
+            </fileset>
+        </path>
+
+        <property name="deploy.xml.property" refid="deploy.xml.files"/>
+
+        <java classname="org.apache.axis.utils.Admin" fork="true">
+            <classpath refid="maven.dependency.classpath"/>
+            <arg value="client"/>
+            <arg file="./target/work/org/apache/ws/axis/oasis/Client_deploy.wsdd"/>
+        </java>
+        
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="maven.dependency.classpath"/>
+            <arg line="${deploy.xml.property}"/>
+        </java>
+    </preGoal>
+
+    <postGoal name="test:test">
+        <echo message="Stopping http server."/>
+
+        <path id="undeploy.xml.files">
+            <fileset dir="./target/work">
+                <include name="**/undeploy.wsdd"/>
+            </fileset>
+        </path>
+
+        <property name="undeploy.xml.property" refid="deploy.xml.files"/>
+
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="maven.dependency.classpath"/>
+            <arg line="${undeploy.xml.property}"/>
+        </java>
+
+
+        <java classname="org.apache.axis.client.AdminClient" fork="yes">
+            <classpath refid="maven.dependency.classpath"/>
+            <arg line="quit"/>
+        </java>
+    </postGoal>
+
+    <postGoal name="jar">
+        <ant:mkdir dir="${basedir}/target/lib"/>
+    </postGoal>
+	<!--
+    <preGoal name="xdoc:jelly-transform">
+      <attainGoal name="html2xdoc"/>
+    </preGoal>  
+	-->
+</project>
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..1b1218c
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,9 @@
+##
+## $Revision$ $Date$
+##
+
+maven.repo.remote=http://people.apache.org/~dims/maven, http://www.ibiblio.org/maven
+maven.xdoc.date=left
+maven.xdoc.version=${pom.currentVersion}
+maven.junit.fork=true
+#maven.html2xdoc.enabled=true
diff --git a/project.xml b/project.xml
new file mode 100644
index 0000000..32cdc38
--- /dev/null
+++ b/project.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0"?>
+
+<project>
+
+  <!-- the version of maven's project object model -->
+  <pomVersion>3</pomVersion>
+  
+  <!-- a unique name for this project -->
+  <id>wss4j</id>
+  
+  <!-- a short but descriptive name for the project -->
+  <name>Apache WSS4J</name>
+  
+  <!-- The version of the project under development, e.g.
+       1.1, 1.2, 2.0-SNAPSHOT -->
+  <currentVersion>1.5</currentVersion>
+  
+  <!-- details about the organization that 'owns' the project -->
+  <organization>
+    <name>Apache Web Services</name>
+    <url>http://ws.apache.org/</url>
+    <logo>http://ws.apache.org/images/project-logo.jpg</logo>
+  </organization>
+  
+  <!-- the year the project started -->
+  <inceptionYear>2004</inceptionYear>
+  <package>org.apache.ws</package>
+  <logo></logo>
+  <description>
+    Apache WSS4J is an implementation of the Web Services Security (WS-Security) being developed at 
+    OASIS Web Services Security TC. WSS4J is a primarily a Java library that can be used to sign and 
+    verify SOAP Messages with WS-Security information. WSS4J will use Apache Axis and Apache XML-Security 
+    projects and will be interoperable with JAX-RPC based server/clients and .NET server/clients. 
+  </description>
+  <!-- a short description of what the project does -->
+  <shortDescription>
+    WS-Security implementation for Apache Axis
+  </shortDescription>
+
+  <!-- the project home page -->
+  <url>http://ws.apache.org/wss4j/</url>
+  <issueTrackingUrl>http://issues.apache.org/jira/browse/WSS</issueTrackingUrl>
+  <siteAddress>ws.apache.org</siteAddress>
+  <siteDirectory>/wss4j/</siteDirectory>
+  <distributionSite>www.apache.org</distributionSite>
+  <distributionDirectory>//dyn/closer.cgi/ws/wss4j/</distributionDirectory>
+
+  <!-- the version control repository and http url for online access
+       the connection element has the form:
+       scm:<system>:<system specific connection string> -->
+  <repository>
+  	<connection>scm:svn:http://svn.apache.org:repos/asf/webservices:wss4j/trunk</connection>
+	<developerConnection>scm:svn:http://svn.apache.org:repos/asf/webservices:wss4j/trunk</developerConnection>
+	<url>http://svn.apache.org/viewcvs.cgi/webservices/wss4j/trunk?root=Apache-SVN</url>
+  </repository>
+
+  <!-- any mailing lists for the project -->
+    <mailingLists>
+        <mailingList>
+            <name>WSS4J Developer List</name>
+            <subscribe>wss4j-dev-subscribe@ws.apache.org</subscribe>
+            <unsubscribe>wss4j-dev-unsubscribe@ws.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/ws-wss4j-dev/</archive>
+        </mailingList>
+    </mailingLists>
+  
+  <!-- who the developers are for the project -->
+  <developers>
+        <developer>
+            <name>Davanum Srinivas</name>
+            <id>dims</id>
+            <email>dims@yahoo.com</email>
+            <organization></organization>
+        </developer>
+        <developer>
+            <name>Werner Dittmann</name>
+            <id>werner</id>
+            <email>werner@apache.org</email>
+            <organization></organization>
+        </developer>
+        <developer>
+            <name>Ias</name>
+            <id>ias</id>
+            <email>ias@apache.org</email>
+            <organization></organization>
+        </developer>
+        <developer>
+            <name>Ruchith Fernando</name>
+            <id>ruchithf</id>
+            <email>ruchithf@apache.org</email>
+            <organization></organization>
+        </developer>
+  </developers>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+  
+  <!-- build information for the project -->
+  <build>
+    <nagEmailAddress>wss4j-dev@ws.apache.org</nagEmailAddress>
+    <sourceDirectory>src</sourceDirectory>
+    <unitTestSourceDirectory>test</unitTestSourceDirectory>
+
+    <unitTest>
+      <includes>
+        <include>**/*PackageTests*.java</include>
+      </includes>
+      <excludes>
+          <exclude>**/wssec/PackageTests.java</exclude>
+          <exclude>**/interop/PackageTests.java</exclude>
+          <exclude>**/TestScenario7.java</exclude>
+      </excludes>
+    </unitTest>
+
+    <resources>
+      <resource>
+        <directory>src</directory>
+        <includes>
+          <include>**/*.properties</include>
+        </includes>
+      </resource>
+    </resources>
+  </build>
+
+    <!-- ============ -->
+    <!-- Dependencies -->
+    <!-- ============ -->
+
+    <dependencies>
+
+        <!-- Module Dependencies -->
+        <!--
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>axis</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>commons-discovery</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>jaxrpc</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>saaj</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>axis</groupId>
+            <artifactId>wsdl4j</artifactId>
+            <version>SNAPSHOT</version>
+            <properties>
+                <module>true</module>
+            </properties>
+        </dependency>
+        -->
+    </dependencies>
+
+    <!-- ======= -->
+    <!-- Reports -->
+    <!-- ======= -->
+
+    <reports>
+        <report>maven-license-plugin</report>
+        <report>maven-checkstyle-plugin</report>
+        <report>maven-pmd-plugin</report>
+        <report>maven-jdepend-plugin</report>
+        <!--<report>maven-changelog-plugin</report> -->
+        <!-- <report>maven-statcvs-plugin</report> -->
+        <!-- <report>maven-file-activity-plugin</report> -->
+        <!-- <report>maven-developer-activity-plugin</report> -->
+        <report>maven-jxr-plugin</report>
+        <report>maven-javadoc-plugin</report>
+        <!-- <report>maven-junit-report-plugin</report> -->
+        <!-- <report>maven-clover-plugin</report> -->
+    </reports>
+    
+</project>
+
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/NStoPkg.properties b/samples/org/apache/ws/axis/samples/wssec/doall/NStoPkg.properties
new file mode 100644
index 0000000..60245df
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/NStoPkg.properties
@@ -0,0 +1 @@
+uri\:axis_sec=org.apache.ws.axis.samples.wssec.doall.axisSec
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/PWCallback.java b/samples/org/apache/ws/axis/samples/wssec/doall/PWCallback.java
new file mode 100644
index 0000000..8224512
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/PWCallback.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ */
+
+package org.apache.ws.axis.samples.wssec.doall;
+
+import org.apache.ws.security.WSPasswordCallback;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.IOException;
+
+public class PWCallback implements CallbackHandler {
+
+    /* (non-Javadoc)
+     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
+     */
+    public void handle(Callback[] callbacks)
+        throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                /*
+                 * here call a function/method to lookup the password for
+                 * the given identifier (e.g. a user name or keystore alias)
+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+                 * for Testing we supply a fixed name here.
+                 */
+                pc.setPassword("security");
+            } else {
+                throw new UnsupportedCallbackException(
+                    callbacks[i],
+                    "Unrecognized Callback");
+            }
+        }
+    }
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/Tester.java b/samples/org/apache/ws/axis/samples/wssec/doall/Tester.java
new file mode 100644
index 0000000..f446cc2
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/Tester.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.samples.wssec.doall;
+
+import org.apache.axis.utils.Options;
+import org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort;
+import org.apache.ws.axis.samples.wssec.doall.axisSec.SecServiceLocator;
+
+
+public class Tester
+{
+
+    private static final java.lang.String address =
+    "http://localhost:8081/axis/services/SecHttp";
+
+
+    public static void main(String [] args) throws Exception {
+        Options opts = new Options(args);
+
+        /*
+          * Start to prepare service call. Once this is done, several
+          * calls can be made on the port (see below)
+         *
+          * Fist: get the service locator. This implements the functionality
+          * to get a client stub (aka port).
+          */
+        SecServiceLocator service = new SecServiceLocator();
+        /* 
+          * this is a JAX-RPC compliant call. It uses a preconfigured
+          * endpoint address (usually contained in the WSDL). Note the
+          * cast.
+          *
+        SecPort port = (SwaPort)service.getPort(SwaPortType.class);
+         */
+
+        /*
+          * Here we use an Axis specific call that allows to override the
+          * port address (service endpoint address) with an own URL. Comes
+          * in handy for testing.
+          */
+        java.net.URL endpoint;
+            try {
+                endpoint = new java.net.URL(address);
+            }
+            catch (java.net.MalformedURLException e) {
+                throw new javax.xml.rpc.ServiceException(e);
+            }
+
+        SecPort port = (SecPort)service.getSecHttp(endpoint);
+        /*
+          * At this point all preparations are done. Using the port we can
+          * now perform as many calls as necessary.
+          */
+    
+         // perform call
+        String result = port.secSend("AppName");
+        System.out.println(result);
+        
+        if (opts.isFlagSet('t') > 0) {
+            long startTime = System.currentTimeMillis();
+            for (int i = 0; i < 20; i++)
+                port.secSend("AppName");
+            long endTime = System.currentTimeMillis();
+            System.out.println("Time used: " + (endTime - startTime) + "ms");
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingImpl.java b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingImpl.java
new file mode 100644
index 0000000..6e3173a
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingImpl.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * SecBindingImpl.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.samples.wssec.doall.axisSec;
+
+public class SecBindingImpl implements org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort{
+    public java.lang.String secSend(java.lang.String applicationName) throws java.rmi.RemoteException {
+        return applicationName;
+    }
+
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingStub.java b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingStub.java
new file mode 100644
index 0000000..554f705
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecBindingStub.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * SecBindingStub.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.samples.wssec.doall.axisSec;
+
+public class SecBindingStub extends org.apache.axis.client.Stub implements org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort {
+    private java.util.Vector cachedSerClasses = new java.util.Vector();
+    private java.util.Vector cachedSerQNames = new java.util.Vector();
+    private java.util.Vector cachedSerFactories = new java.util.Vector();
+    private java.util.Vector cachedDeserFactories = new java.util.Vector();
+
+    static org.apache.axis.description.OperationDesc [] _operations;
+
+    static {
+        _operations = new org.apache.axis.description.OperationDesc[1];
+        _initOperationDesc1();
+    }
+
+    private static void _initOperationDesc1(){
+        org.apache.axis.description.OperationDesc oper;
+        oper = new org.apache.axis.description.OperationDesc();
+        oper.setName("secSend");
+        oper.addParameter(new javax.xml.namespace.QName("", "applicationName"), new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, org.apache.axis.description.ParameterDesc.IN, false, false);
+        oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
+        oper.setReturnClass(java.lang.String.class);
+        oper.setReturnQName(new javax.xml.namespace.QName("", "return"));
+        oper.setStyle(org.apache.axis.constants.Style.RPC);
+        oper.setUse(org.apache.axis.constants.Use.LITERAL);
+        _operations[0] = oper;
+
+    }
+
+    public SecBindingStub() throws org.apache.axis.AxisFault {
+         this(null);
+    }
+
+    public SecBindingStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
+         this(service);
+         super.cachedEndpoint = endpointURL;
+    }
+
+    public SecBindingStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
+        if (service == null) {
+            super.service = new org.apache.axis.client.Service();
+        } else {
+            super.service = service;
+        }
+    }
+
+    private org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {
+        try {
+            org.apache.axis.client.Call _call =
+                    (org.apache.axis.client.Call) super.service.createCall();
+            if (super.maintainSessionSet) {
+                _call.setMaintainSession(super.maintainSession);
+            }
+            if (super.cachedUsername != null) {
+                _call.setUsername(super.cachedUsername);
+            }
+            if (super.cachedPassword != null) {
+                _call.setPassword(super.cachedPassword);
+            }
+            if (super.cachedEndpoint != null) {
+                _call.setTargetEndpointAddress(super.cachedEndpoint);
+            }
+            if (super.cachedTimeout != null) {
+                _call.setTimeout(super.cachedTimeout);
+            }
+            if (super.cachedPortName != null) {
+                _call.setPortName(super.cachedPortName);
+            }
+            java.util.Enumeration keys = super.cachedProperties.keys();
+            while (keys.hasMoreElements()) {
+                java.lang.String key = (java.lang.String) keys.nextElement();
+                _call.setProperty(key, super.cachedProperties.get(key));
+            }
+            return _call;
+        }
+        catch (java.lang.Throwable t) {
+            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", t);
+        }
+    }
+
+    public java.lang.String secSend(java.lang.String applicationName) throws java.rmi.RemoteException {
+        if (super.cachedEndpoint == null) {
+            throw new org.apache.axis.NoEndPointException();
+        }
+        org.apache.axis.client.Call _call = createCall();
+        _call.setOperation(_operations[0]);
+        _call.setUseSOAPAction(true);
+        _call.setSOAPActionURI("secSend");
+        _call.setEncodingStyle(null);
+        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
+        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
+        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+        _call.setOperationName(new javax.xml.namespace.QName("", "secSend"));
+
+        setRequestHeaders(_call);
+        setAttachments(_call);
+        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {applicationName});
+
+        if (_resp instanceof java.rmi.RemoteException) {
+            throw (java.rmi.RemoteException)_resp;
+        }
+        else {
+            extractAttachments(_call);
+            try {
+                return (java.lang.String) _resp;
+            } catch (java.lang.Exception _exception) {
+                return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class);
+            }
+        }
+    }
+
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecPort.java b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecPort.java
new file mode 100644
index 0000000..c4876be
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecPort.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * SecPort.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.samples.wssec.doall.axisSec;
+
+public interface SecPort extends java.rmi.Remote {
+    public java.lang.String secSend(java.lang.String applicationName) throws java.rmi.RemoteException;
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecService.java b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecService.java
new file mode 100644
index 0000000..bf4711b
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * SecService.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.samples.wssec.doall.axisSec;
+
+public interface SecService extends javax.xml.rpc.Service {
+    public java.lang.String getSecHttpAddress();
+
+    public org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort getSecHttp() throws javax.xml.rpc.ServiceException;
+
+    public org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort getSecHttp(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecServiceLocator.java b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecServiceLocator.java
new file mode 100644
index 0000000..a010d90
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/SecServiceLocator.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/**
+ * SecServiceLocator.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis 1.2dev Oct 27, 2003 (02:34:09 EST) WSDL2Java emitter.
+ */
+
+package org.apache.ws.axis.samples.wssec.doall.axisSec;
+
+public class SecServiceLocator extends org.apache.axis.client.Service implements org.apache.ws.axis.samples.wssec.doall.axisSec.SecService {
+
+    // Use to get a proxy class for SecHttp
+    private java.lang.String SecHttp_address = "http://localhost:8081/axis/services/secHttp";
+
+    public java.lang.String getSecHttpAddress() {
+        return SecHttp_address;
+    }
+
+    // The WSDD service name defaults to the port name.
+    private java.lang.String SecHttpWSDDServiceName = "SecHttp";
+
+    public java.lang.String getSecHttpWSDDServiceName() {
+        return SecHttpWSDDServiceName;
+    }
+
+    public void setSecHttpWSDDServiceName(java.lang.String name) {
+        SecHttpWSDDServiceName = name;
+    }
+
+    public org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort getSecHttp() throws javax.xml.rpc.ServiceException {
+       java.net.URL endpoint;
+        try {
+            endpoint = new java.net.URL(SecHttp_address);
+        }
+        catch (java.net.MalformedURLException e) {
+            throw new javax.xml.rpc.ServiceException(e);
+        }
+        return getSecHttp(endpoint);
+    }
+
+    public org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort getSecHttp(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
+        try {
+            org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingStub _stub = new org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingStub(portAddress, this);
+            _stub.setPortName(getSecHttpWSDDServiceName());
+            return _stub;
+        }
+        catch (org.apache.axis.AxisFault e) {
+            return null;
+        }
+    }
+
+    public void setSecHttpEndpointAddress(java.lang.String address) {
+        SecHttp_address = address;
+    }
+
+    /**
+     * For the given interface, get the stub implementation.
+     * If this service has no port for the given interface,
+     * then ServiceException is thrown.
+     */
+    public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
+        try {
+            if (org.apache.ws.axis.samples.wssec.doall.axisSec.SecPort.class.isAssignableFrom(serviceEndpointInterface)) {
+                org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingStub _stub = new org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingStub(new java.net.URL(SecHttp_address), this);
+                _stub.setPortName(getSecHttpWSDDServiceName());
+                return _stub;
+            }
+        }
+        catch (java.lang.Throwable t) {
+            throw new javax.xml.rpc.ServiceException(t);
+        }
+        throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface:  " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
+    }
+
+    /**
+     * For the given interface, get the stub implementation.
+     * If this service has no port for the given interface,
+     * then ServiceException is thrown.
+     */
+    public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
+        if (portName == null) {
+            return getPort(serviceEndpointInterface);
+        }
+        String inputPortName = portName.getLocalPart();
+        if ("SecHttp".equals(inputPortName)) {
+            return getSecHttp();
+        }
+        else  {
+            java.rmi.Remote _stub = getPort(serviceEndpointInterface);
+            ((org.apache.axis.client.Stub) _stub).setPortName(portName);
+            return _stub;
+        }
+    }
+
+    public javax.xml.namespace.QName getServiceName() {
+        return new javax.xml.namespace.QName("uri:axis_sec", "secService");
+    }
+
+    private java.util.HashSet ports = null;
+
+    public java.util.Iterator getPorts() {
+        if (ports == null) {
+            ports = new java.util.HashSet();
+            ports.add(new javax.xml.namespace.QName("SecHttp"));
+        }
+        return ports.iterator();
+    }
+
+    /**
+    * Set the endpoint address for the specified port name.
+    */
+    public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
+        if ("SecHttp".equals(portName)) {
+            setSecHttpEndpointAddress(address);
+        }
+        else { // Unknown Port Name
+            throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
+        }
+    }
+
+    /**
+    * Set the endpoint address for the specified port name.
+    */
+    public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
+        setEndpointAddress(portName.getLocalPart(), address);
+    }
+
+}
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/deploy.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/deploy.wsdd
new file mode 100644
index 0000000..ba16bc1
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/deploy.wsdd
@@ -0,0 +1,27 @@
+<!-- Use this file to deploy some handlers/chains and services      -->
+<!-- Two ways to do this:                                           -->
+<!--   java org.apache.axis.client.AdminClient deploy.wsdd          -->
+<!--      after the axis server is running                          -->
+<!-- or                                                             -->
+<!--   java org.apache.axis.utils.Admin client|server deploy.wsdd   -->
+<!--      from the same directory that the Axis engine runs         -->
+
+<deployment
+    xmlns="http://xml.apache.org/axis/wsdd/"
+    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+
+  <!-- Services from secService WSDL service -->
+
+  <service name="SecHttp" provider="java:RPC" style="rpc" use="literal">
+      <parameter name="wsdlTargetNamespace" value="uri:axis_sec"/>
+      <parameter name="wsdlServiceElement" value="secService"/>
+      <parameter name="wsdlServicePort" value="SecHttp"/>
+      <parameter name="className" value="org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingImpl"/>
+      <parameter name="wsdlPortType" value="secPort"/>
+      <operation name="secSend" qname="secSend" returnQName="return" returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema" >
+        <parameter name="applicationName" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
+      </operation>
+      <parameter name="allowedMethods" value="secSend"/>
+
+  </service>
+</deployment>
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/undeploy.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/undeploy.wsdd
new file mode 100644
index 0000000..1886f0c
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/axisSec/undeploy.wsdd
@@ -0,0 +1,15 @@
+<!-- Use this file to undeploy some handlers/chains and services    -->
+<!-- Two ways to do this:                                           -->
+<!--   java org.apache.axis.client.AdminClient undeploy.wsdd        -->
+<!--      after the axis server is running                          -->
+<!-- or                                                             -->
+<!--   java org.apache.axis.utils.Admin client|server undeploy.wsdd -->
+<!--      from the same directory that the Axis engine runs         -->
+
+<undeployment
+    xmlns="http://xml.apache.org/axis/wsdd/">
+
+  <!-- Services from secService WSDL service -->
+
+  <service name="SecHttp"/>
+</undeployment>
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/build.xml b/samples/org/apache/ws/axis/samples/wssec/doall/build.xml
new file mode 100644
index 0000000..1977623
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/build.xml
@@ -0,0 +1,68 @@
+<project name="Axis_SecDoAll" default="wsdl2java" basedir=".">
+    <description>
+        generate files from WSDL description, also target to deploy
+        the service in a runing Axis (probably in Tomcat or alike)
+    </description>
+
+  <!-- The following setting assumes that all necessary libs (jars)
+    are located in a lib directory directly under wss4j. First set
+    a reference to the wss4j relative to this working directory -->
+  <property name="dir.wss4j" value="../../../../../../../.." />
+  <property name="dir.libs"  value="${dir.wss4j}/lib" />
+
+  <!-- Base directory where to put generated java files -->
+  <property name="WSDLGenFiles" location="${dir.wss4j}/samples" />
+  <!-- where to find the SwA WSDL files -->
+  <property name="WSDLDir" location="${basedir}" />
+
+  <!--
+   Directory of the generated Java files
+  -->
+  <property name="sec" value="org/apache/ws/axis/samples/wssec/doall/axisSec" />
+
+    <path id="classpath.libraries" description=" 3rd party and Axis libs">
+      <fileset dir="${dir.libs}">
+        <include name="**/*.jar"/>
+	<!-- <pathelement path="${java.class.path}"/> -->
+      </fileset>
+    </path>
+  
+  <target name="clientdeploy">
+    <java classname="org.apache.axis.utils.Admin" fork="true">
+      <classpath refid="classpath.libraries" />
+      <arg value="client"/>
+      <arg file="${WSDLDir}/client_deploy.wsdd" />
+    </java>
+  </target>
+
+  <target name="serverdeploy">
+    <java classname="org.apache.axis.client.AdminClient" fork="true">
+      <classpath refid="classpath.libraries" />
+      <arg file="${WSDLDir}/server_deploy.wsdd" />
+    </java>
+  </target>
+
+  <target name="serverundeploy">
+    <java classname="org.apache.axis.client.AdminClient" fork="true">
+      <classpath refid="classpath.libraries" />
+     <arg file="${WSDLGenFiles}/${sec}/undeploy.wsdd" />
+    </java>
+  </target>
+
+  <target name="wsdl2java">
+    <java classname="org.apache.axis.wsdl.WSDL2Java" fork="true">
+      <classpath refid="classpath.libraries" />
+      <arg value="-f" /> 
+      <arg file="${WSDLDir}/NStoPkg.properties" /> 
+      <arg value="-S true" />
+      <arg value="-o" />
+      <arg file="${WSDLGenFiles}" />
+      <arg file="${WSDLDir}/sec.wsdl" />
+    </java>
+  </target>
+
+  <target name="clean"
+        description="clean up" >
+    <delete dir="${WSDLGenFiles}/${sec}"/>
+  </target>
+</project>
\ No newline at end of file
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/client-config.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/client-config.wsdd
new file mode 100644
index 0000000..5612729
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/client-config.wsdd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+ <service name="SecHttp">
+  <requestFlow>
+   <handler name="DoSecuritySender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<!-- <parameter name="action" value="Encrypt Signatur"/> -->
+    <parameter name="action" value="Signature Encrypt"/>
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="encryptionPropFile" value="crypto.properties" /> -->
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" />
+	<!-- <parameter name="encryptionParts" value="{Content}{http://example.org/paymentv2}CreditCard;{Element}{}UserName" /> -->
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler name="DoSecurityReceiver" type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<parameter name="action" value="Encrypt Signature"/>
+    <!-- <parameter name="action" value="Signature Encrypt"/> -->
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="decryptionPropFile" value="crypto.properties" /> -->
+   </handler>
+  </responseFlow>
+  
+ </service>
+ <transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender"/>
+ <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
+ <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender"/>
+</deployment>
\ No newline at end of file
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/client_deploy.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/client_deploy.wsdd
new file mode 100644
index 0000000..376b331
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/client_deploy.wsdd
@@ -0,0 +1,34 @@
+<deployment xmlns="http://xml.apache.org/axis/wsdd/"
+            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+
+ <!-- define the service, using the WSDoAllSender security handler in request flow -->
+ <service name="SecHttp">
+  <requestFlow>
+   <handler name="DoSecuritySender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<!-- <parameter name="action" value="Encrypt Signatur"/> -->
+    <parameter name="action" value="Signature Encrypt"/>
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="encryptionPropFile" value="crypto.properties" /> -->
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" />
+	<!-- <parameter name="encryptionParts" value="{Content}{http://example.org/paymentv2}CreditCard;{Element}{}UserName" /> -->
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler name="DoSecurityReceiver" type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<parameter name="action" value="Encrypt Signature"/>
+    <!-- <parameter name="action" value="Signature Encrypt"/> -->
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="decryptionPropFile" value="crypto.properties" /> -->
+   </handler>
+  </responseFlow>
+ </service>
+
+</deployment>
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/keys/x509.PFX.MSFT b/samples/org/apache/ws/axis/samples/wssec/doall/keys/x509.PFX.MSFT
new file mode 100644
index 0000000..98be0df
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/keys/x509.PFX.MSFT
Binary files differ
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/log4j.properties b/samples/org/apache/ws/axis/samples/wssec/doall/log4j.properties
new file mode 100644
index 0000000..62cd524
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/log4j.properties
@@ -0,0 +1,26 @@
+# Set root category priority to INFO and its only appender to CONSOLE.
+log4j.rootCategory=FATAL, CONSOLE
+# log4j.rootCategory=DEBUG, CONSOLE, LOGFILE
+
+# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
+log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
+# log4j.logger.org.apache.axis.i18n.ProjectResourceBundle=INFO
+log4j.logger.org.apache.ws.security.TIME=DEBUG
+# log4j.logger.org.apache.ws.security.message.EnvelopeIdResolver=INFO
+# log4j.logger.org.apache.ws.axis.security.WSDoAllSender=INFO
+# log4j.logger.org.apache.ws.security.WSSecurityEngine=INFO
+# log4j.logger.org.apache.xml.security.encryption.XMLCipher=DEBUG
+
+# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.Threshold=DEBUG
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n
+
+# LOGFILE is set to be a File appender using a PatternLayout.
+log4j.appender.LOGFILE=org.apache.log4j.FileAppender
+log4j.appender.LOGFILE.File=axis.log
+log4j.appender.LOGFILE.Append=true
+log4j.appender.LOGFILE.Threshold=DEBUG
+log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/sec.wsdl b/samples/org/apache/ws/axis/samples/wssec/doall/sec.wsdl
new file mode 100644
index 0000000..b4a2d77
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/sec.wsdl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions name="Axis_sec"
+   targetNamespace="uri:axis_sec"
+   xmlns:swa="uri:axis_sec"
+   xmlns="http://schemas.xmlsoap.org/wsdl/"
+   xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
+   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   >
+
+   <message name="SecRequest">
+      <part name="applicationName" type="xsd:string"/>
+   </message>
+
+   <message name="SecResponse">
+      <part name="return" type="xsd:string"/>
+   </message>
+
+   <portType name="secPort">
+      <operation name="secSend">
+         <input message="swa:SecRequest"/>
+	 <output message="swa:SecResponse"/>
+      </operation>
+   </portType>
+
+   <binding name="secBinding" type="swa:secPort">
+     <soap:binding style="rpc" transport= "http://schemas.xmlsoap.org/soap/http"/>
+     <operation name="secSend">
+       <soap:operation soapAction="secSend" />
+	   <input>
+	     <soap:body use="literal" parts="applicationName" />
+	   </input>
+	   <output>
+	    <soap:body use="literal" />
+	   </output>
+     </operation>
+   </binding>
+
+   <service name="secService">
+      <port name="SecHttp" binding="swa:secBinding">
+         <soap:address location="http://localhost:8081/axis/services/secHttp"/>
+      </port>
+   </service>
+</definitions>
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/server-config.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/server-config.wsdd
new file mode 100644
index 0000000..7680f9e
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/server-config.wsdd
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+ <globalConfiguration>
+  <parameter name="adminPassword" value="admin"/>
+  <parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
+  <parameter name="sendXsiTypes" value="true"/>
+  <parameter name="sendMultiRefs" value="true"/>
+  <parameter name="sendXMLDeclaration" value="true"/>
+  <requestFlow>
+   <handler type="java:org.apache.axis.handlers.JWSHandler">
+    <parameter name="scope" value="session"/>
+   </handler>
+   <handler type="java:org.apache.axis.handlers.JWSHandler">
+    <parameter name="scope" value="request"/>
+    <parameter name="extension" value=".jwr"/>
+   </handler>
+  </requestFlow>
+ </globalConfiguration>
+ <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
+ <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
+ <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
+ <service name="SecHttp" provider="java:RPC" use="literal">
+  <operation name="secSend" qname="secSend" returnQName="return" returnType="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+   <parameter name="applicationName" type="xsd:string"/>
+  </operation>
+  <requestFlow>
+   <handler name="DoSecurityReceiver" type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<!-- <parameter name="action" value="Encrypt Signature"/> -->
+    <parameter name="action" value="Signature Encrypt"/>
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="decryptionPropFile" value="crypto.properties" /> -->
+   </handler>
+  </requestFlow>
+  <responseFlow>
+   <handler name="DoSecuritySender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<parameter name="action" value="Encrypt Signature"/>
+    <!-- <parameter name="action" value="Signature Encrypt"/> -->
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="encryptionPropFile" value="crypto.properties" /> -->
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" />
+   </handler>
+  
+  </responseFlow>
+  <parameter name="allowedMethods" value="secSend"/>
+  <parameter name="wsdlPortType" value="secPort"/>
+  <parameter name="className" value="org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingImpl"/>
+  <parameter name="wsdlServicePort" value="SecHttp"/>
+  <parameter name="wsdlTargetNamespace" value="uri:axis_sec"/>
+  <parameter name="wsdlServiceElement" value="secService"/>
+ </service>
+ <service name="AdminService" provider="java:MSG">
+  <parameter name="allowedMethods" value="AdminService"/>
+  <parameter name="enableRemoteAdmin" value="false"/>
+  <parameter name="className" value="org.apache.axis.utils.Admin"/>
+  <namespace>http://xml.apache.org/axis/wsdd/</namespace>
+ </service>
+ <service name="Version" provider="java:RPC">
+  <parameter name="allowedMethods" value="getVersion"/>
+  <parameter name="className" value="org.apache.axis.Version"/>
+ </service>
+ <transport name="http">
+  <requestFlow>
+   <handler type="URLMapper"/>
+   <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
+  </requestFlow>
+  <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
+  <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
+  <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
+ </transport>
+ <transport name="local">
+  <responseFlow>
+   <handler type="LocalResponder"/>
+  </responseFlow>
+ </transport>
+</deployment>
\ No newline at end of file
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/server_deploy.wsdd b/samples/org/apache/ws/axis/samples/wssec/doall/server_deploy.wsdd
new file mode 100644
index 0000000..405db38
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/server_deploy.wsdd
@@ -0,0 +1,51 @@
+<!-- Use this file to deploy some handlers/chains and services      -->
+<!-- Two ways to do this:                                           -->
+<!--   java org.apache.axis.client.AdminClient deploy.wsdd          -->
+<!--      after the axis server is running                          -->
+<!-- or                                                             -->
+<!--   java org.apache.axis.utils.Admin client|server deploy.wsdd   -->
+<!--      from the same directory that the Axis engine runs         -->
+
+<deployment
+    xmlns="http://xml.apache.org/axis/wsdd/"
+    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
+
+  <!-- Services from secService WSDL service -->
+
+  <service name="SecHttp" provider="java:RPC" style="rpc" use="literal">
+    <parameter name="wsdlTargetNamespace" value="uri:axis_sec"/>
+    <parameter name="wsdlServiceElement" value="secService"/>
+    <parameter name="wsdlServicePort" value="SecHttp"/>
+    <parameter name="className" value="org.apache.ws.axis.samples.wssec.doall.axisSec.SecBindingImpl"/>
+    <parameter name="wsdlPortType" value="secPort"/>
+    <operation name="secSend" qname="secSend" returnQName="return" returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema" >
+      <parameter name="applicationName" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
+    </operation>
+    <parameter name="allowedMethods" value="secSend"/>
+    <requestFlow>
+      <handler name="DoSecurityReceiver" type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+       <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+       <!-- <parameter name="action" value="Signature"/> -->
+	   <!-- <parameter name="action" value="Encrypt Signature"/> -->
+       <parameter name="action" value="Signature Encrypt"/>
+       <!-- <parameter name="action" value="Encrypt"/> -->
+       <parameter name="signaturePropFile" value="crypto.properties" />
+       <!-- <parameter name="decryptionPropFile" value="crypto.properties" /> -->
+	  </handler>
+ 	</requestFlow>
+  <responseFlow>
+   <handler name="DoSecuritySender" type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    <parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    <parameter name="passwordCallbackClass" value="org.apache.ws.axis.samples.wssec.doall.PWCallback"/>
+    <!-- <parameter name="action" value="Signature"/> -->
+	<parameter name="action" value="Encrypt Signature"/>
+    <!-- <parameter name="action" value="Signature Encrypt"/> -->
+    <!-- <parameter name="action" value="Encrypt"/> -->
+    <parameter name="signaturePropFile" value="crypto.properties" />
+    <!-- <parameter name="encryptionPropFile" value="crypto.properties" /> -->
+    <parameter name="signatureKeyIdentifier" value="DirectReference" />
+    <parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" />
+   </handler>
+  </responseFlow>
+  </service>
+</deployment>
diff --git a/samples/org/apache/ws/axis/samples/wssec/doall/simplelog.properties b/samples/org/apache/ws/axis/samples/wssec/doall/simplelog.properties
new file mode 100644
index 0000000..79794d5
--- /dev/null
+++ b/samples/org/apache/ws/axis/samples/wssec/doall/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+
diff --git a/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenService.java b/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenService.java
new file mode 100644
index 0000000..3e2da21
--- /dev/null
+++ b/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenService.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.samples;
+
+import org.apache.ws.sandbox.security.trust2.Lifetime;
+import org.apache.ws.sandbox.security.trust2.RequestSecurityToken;
+import org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust2.SecurityTokenOrReference;
+import org.apache.ws.sandbox.security.trust2.TokenTypes;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.apache.axis.AxisFault;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.WSSConfig;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A WS-Trust style security token service. It is intended to be used as an Axis Docmument-style service.
+ */
+public class SampleSecurityTokenService {
+
+    // Service has a single method called exchange. Really since its a Document service, the method name is arbitrary
+    // and won't show up anywhere in the XML of the request. An exchange operation must be properly defined in the
+    // Axis WSDD configuration file for this service. Then if Axis sees a SOAP body containing a RequestSecurityToken 
+    // element in the WS-Trust namespace it will invoke this method. Assuming that the deserializers are configured 
+    // correctly in the WSDD file, Axis should be able to automatically convert the XML into a RequestSecurityToken
+    // object as well. 
+    public RequestSecurityTokenResponse exchange(RequestSecurityToken tokenRequest) throws AxisFault {
+        if (tokenRequest != null) {
+            // Check the request type, this service only understands requests for token issue
+            if (TrustConstants.REQUEST_ISSUE.equals(tokenRequest.getRequestType())) {
+                SecurityTokenOrReference requestedToken = null;
+                Document doc = tokenRequest.getDocument();
+				
+                // Check the token type being requested, this service returns only X509 certs or UsernameTokens 
+                if (TokenTypes.X509.equals(tokenRequest.getTokenType())) {
+                    try {
+                        // Construct an arbitrary x509 certificate (certificate content is hard-coded) any x509 request returns the same certificate
+                        // A real service would do something more intelligent
+                        InputStream inputStream = new ByteArrayInputStream("-----BEGIN CERTIFICATE-----\nMIICTTCCAbagAwIBAgIDC6tXMA0GCSqGSIb3DQEBBAUAMGExCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCYXllcm4xDzANBgNVBAcTBk11bmljaDEPMA0GA1UEChMGQXBhY2hlMQ4wDAYDVQQLEwVXU1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA0MDUxMDA2MjgzMloXDTA0MDUxMDE4MzMzMlowdjELMAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNVBAsTBVdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIxEzARBgNVBAMTCjEzNDU1MDc0NzQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJbir9ayJesk3Yj+L1gDlS8TbtEj5DYLMhIYDA/Ycef2WEQ+pNIPTpeZ27SYEgf8Kmxpt4HHE5WJ8M9wnpB6EDQwi8vIQLTkaemJHGuWH8rbFY4CwFtQKEro63+agiSzbWZkpOFX4RFyX/Y5lOgZcW0q0yhumG2ZdMKViS81gx4BAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAPxYMCzAIoe0/DhT2NPpfl8+3vHV33YIbzlaejoV47KeR9IjPvKNS3PK0Mke3eKgJo/11DplnVpx9inKYaatPT/ZRz0eJ1+oTPe1kRYMDhO/OWCZhvVWQZPA9M8TWrDWJKwa6HlEmsbZGMnoGwEQ+7S3eD9TsqFf83CD+6Yr8wkM=\n-----END CERTIFICATE-----".getBytes());
+                        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+                        X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
+						
+                        // Add the cert to a <BinarySecurityToken> element
+                        X509Security binaryToken = new X509Security(doc);
+                        binaryToken.setX509Certificate(cert);
+						
+                        // Set the <BinarySecurityToken> as the <RequestedToken> in our response
+                        requestedToken = new SecurityTokenOrReference(binaryToken);
+                    } catch (Exception e) {
+                        throw new AxisFault("Could not create X.509 Security Token: " + e.getMessage());
+                    }
+                } else if (TokenTypes.USERNAME.equals(tokenRequest.getTokenType())) {
+                    // Create an arbitrary, fixed UsernameToken to return if the client requests one
+                    // A real security token service would do something more intelligent
+                    UsernameToken userToken = new UsernameToken(WSSConfig.getDefaultWSConfig().isPrecisionInMilliSeconds(),doc);
+                    userToken.setName("bob");
+                    userToken.setPassword("bobspass");
+					
+                    // Create a new SecurityTokenOrReference object to use for the <RequestedToken> element
+                    // As the class name implies SecurityTokenOrReference objects can hold either a real security token element
+                    // or a <SecurityTokenReference> element to a security token found elsewhere 
+                    requestedToken = new SecurityTokenOrReference(userToken);
+                }
+				
+                // Create our response object, giving it an XML document object to use for element creation, along with our requestedToken object
+                RequestSecurityTokenResponse tokenResponse = new RequestSecurityTokenResponse(doc, requestedToken);
+				
+                // Set the Context of the response, according to WS-Trust, this must be the same as the Context of the request
+                tokenResponse.setContext(tokenRequest.getContext());
+				
+                // Set the TokenType of the response. To make clients happy we'll return a token of the type they requested
+                tokenResponse.setTokenType(tokenRequest.getTokenType());
+				
+                // Add a Lifetime element to indicate to clients the lifetime of the token we're sending
+                // In this case, we're giving the client the lifetime they asked for 
+                Lifetime lifetime = tokenRequest.getLifetime();
+                tokenResponse.setLifetime(lifetime);
+
+                // Check if the request included a custom element named <TestElement>
+                // Note that a list of custom elements can be obtained by calling getCustomElements();
+                if (tokenRequest.getCustomElement("http://testElementNs.testElementNs", "TestElement") != null) {
+                    // If it did we'll add our own custom element to the response
+                    tokenResponse.addCustomElementNS("http://testElementNs.testElementNs", "te:TestElementResponse");
+                }
+				
+                // Return the response object. If our Axis Serializers are configured correctly, this should automatically get converted to XML
+                return tokenResponse;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenServiceClient.java b/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenServiceClient.java
new file mode 100644
index 0000000..da68981
--- /dev/null
+++ b/samples/org/apache/ws/sandbox/security/trust2/samples/SampleSecurityTokenServiceClient.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.samples;
+
+import org.apache.ws.sandbox.security.trust2.Lifetime;
+import org.apache.ws.sandbox.security.trust2.RequestSecurityToken;
+import org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust2.SecurityTokenOrReference;
+import org.apache.ws.sandbox.security.trust2.TokenTypes;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.apache.axis.client.Call;
+import org.apache.axis.client.Service;
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.utils.Options;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.WSSConfig;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+
+import java.net.URI;
+import java.util.Date;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A client class to test the SecurityTokenService.
+ */
+public class SampleSecurityTokenServiceClient {
+
+    /** Field address */
+    private static final java.lang.String address =
+            "http://localhost:8080/axis/services/SampleSecurityTokenService";
+
+    
+    // First arg passed should be the URL of the service. If none is specified, client tries localhost.
+    public static void main(String[] args) throws DOMException, TrustException, Exception {
+
+        Options opts = new Options(args);
+        opts.setDefaultURL(address);
+
+        Service service = new Service();
+        Call call = (Call) service.createCall();
+        call.setTargetEndpointAddress(opts.getURL());
+
+        SOAPEnvelope env = new SOAPEnvelope();
+        Document doc = env.getAsDocument();
+        WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+
+        // Create a new request object passing an XML document for element creation and the RequestType (in this case issue)
+        RequestSecurityToken tokenRequest = new RequestSecurityToken(doc, TrustConstants.REQUEST_ISSUE);
+		
+        // Setting the context and the token type we want to be returned
+        tokenRequest.setContext(new URI("http://context.context"));
+        tokenRequest.setTokenType(TokenTypes.X509);
+		
+        // Construct a bunch of username tokens to be used as <Base> and <Supporting> elements
+        UsernameToken userToken = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        userToken.setName("bob");
+        userToken.setPassword("bobspass");
+        tokenRequest.setBase(new SecurityTokenOrReference(userToken));
+
+        UsernameToken user2Token = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        user2Token.setName("joe");
+        user2Token.setPassword("bobspass");
+        tokenRequest.addSupporting(new SecurityTokenOrReference(user2Token));
+
+        UsernameToken user3Token = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        user3Token.setName("mike");
+        user3Token.setPassword("bobspass");
+        tokenRequest.addSupporting(new SecurityTokenOrReference(user3Token));
+
+        // Set the desired Lifetime of the token being requested in this case to 250 seconds
+        Date start = new Date();
+        Date end = new Date();
+        end.setTime(start.getTime() + 250 * 1000);
+        tokenRequest.setLifetime(new Lifetime(wssConfig, doc, start, end));
+
+        // Add a custom element of our own creation
+        tokenRequest.addCustomElementNS("http://testElementNs.testElementNs", "te:TestElement");
+
+        // Create a SOAP body and set the XML element of the token request (a <RequestSecurityToken> element)
+        // as its only child
+        SOAPBodyElement sbe = new SOAPBodyElement(tokenRequest.getElement());
+
+        // Add the body element to the SOAP envelope
+        env.addBodyElement(sbe);
+
+        System.out.println("\n============= Request ==============");
+        System.out.println(XMLUtils.DocumentToString(env.getAsDocument()));
+		
+        // This is where we actually invoke the service, sending the request we've constructed
+        // Assuming we did everything right, it will return to us a SOAP envelope containing the response
+        SOAPEnvelope response = call.invoke(env);
+
+        System.out.println("\n============= Response ==============");
+        XMLUtils.PrettyElementToStream(response.getAsDOM(), System.out);
+		
+        // Find the <RequestSecurityTokenResponse> element the SOAP body should contain
+        SOAPBodyElement responseBody = response.getBodyByName(TrustConstants.WST_NS, TrustConstants.RESPONSE_TAG);
+
+        // Construct a Java object from the XML
+        RequestSecurityTokenResponse tokenResponse = new RequestSecurityTokenResponse(responseBody.getAsDOM());
+
+        System.out.println("\n------- RequestSecurityTokenResponse object ------------- \n" + tokenResponse);
+    }
+}
diff --git a/samples/org/apache/ws/sandbox/security/trust2/samples/deploy.wsdd b/samples/org/apache/ws/sandbox/security/trust2/samples/deploy.wsdd
new file mode 100644
index 0000000..33976a9
--- /dev/null
+++ b/samples/org/apache/ws/sandbox/security/trust2/samples/deploy.wsdd
@@ -0,0 +1,24 @@
+<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

+	<service name="SampleSecurityTokenService" style="document" use="literal">

+  		<parameter name="allowedMethods" value="*"/>

+  		<parameter name="className" value="org.apache.ws.sandbox.security.trust2.samples.SampleSecurityTokenService"/>

+		<typeMapping

+	        xmlns:ns="http://schemas.xmlsoap.org/ws/2004/04/trust"

+    	    qname="ns:RequestSecurityToken"

+        	type="java:org.apache.ws.sandbox.security.trust2.RequestSecurityToken"

+	        serializer="org.apache.ws.sandbox.security.trust2.serialization.RSTSerializerFactory"

+    	    deserializer="org.apache.ws.sandbox.security.trust2.serialization.RSTDeserializerFactory"

+	        encodingStyle=""/>

+		<typeMapping

+	        xmlns:ns="http://schemas.xmlsoap.org/ws/2004/04/trust"

+    	    qname="ns:RequestSecurityTokenResponse"

+        	type="java:org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse"

+	        serializer="org.apache.ws.sandbox.security.trust2.serialization.RSTResponseSerializerFactory"

+    	    deserializer="org.apache.ws.sandbox.security.trust2.serialization.RSTResponseDeserializerFactory"

+	        encodingStyle=""/>	

+		<operation name="exchange" qname="ns1:RequestSecurityToken" xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/04/trust"

+			returnQName="ns1:RequestSecurityTokenResponse" returnType="ns1:RequestSecurityTokenResponse">

+			<parameter qname="ns1:RequestSecurityToken" type="ns1:RequestSecurityToken" xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/04/trust"/>

+		</operation>

+ 	</service>

+</deployment>

diff --git a/samples/org/apache/ws/sandbox/security/trust2/samples/undeploy.wsdd b/samples/org/apache/ws/sandbox/security/trust2/samples/undeploy.wsdd
new file mode 100644
index 0000000..77fef12
--- /dev/null
+++ b/samples/org/apache/ws/sandbox/security/trust2/samples/undeploy.wsdd
@@ -0,0 +1,12 @@
+<!-- Use this file to undeploy some handlers/chains and services    -->

+<!-- Two ways to do this:                                           -->

+<!--   java org.apache.axis.client.AdminClient undeploy.wsdd        -->

+<!--      after the axis server is running                          -->

+<!-- or                                                             -->

+<!--   java org.apache.axis.utils.Admin client|server undeploy.wsdd -->

+<!--      from the same directory that the Axis engine runs         -->

+

+<undeployment

+    xmlns="http://xml.apache.org/axis/wsdd/">

+  <service name="SampleSecurityTokenService"/>

+</undeployment>
\ No newline at end of file
diff --git a/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04-change-bars.pdf b/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04-change-bars.pdf
new file mode 100644
index 0000000..0567d6d
--- /dev/null
+++ b/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04-change-bars.pdf
Binary files differ
diff --git a/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04.pdf b/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04.pdf
new file mode 100644
index 0000000..ef05284
--- /dev/null
+++ b/specs/WSS-SAML-TOKEN-PROFILE-1.1-wd-04.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-kerberos-token-profile-1.1-CD.pdf b/specs/oasis-2005xx-wss-kerberos-token-profile-1.1-CD.pdf
new file mode 100644
index 0000000..497fa04
--- /dev/null
+++ b/specs/oasis-2005xx-wss-kerberos-token-profile-1.1-CD.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-soap-message-security-1.1-CD.pdf b/specs/oasis-2005xx-wss-soap-message-security-1.1-CD.pdf
new file mode 100644
index 0000000..61e72d4
--- /dev/null
+++ b/specs/oasis-2005xx-wss-soap-message-security-1.1-CD.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-soap-message-security-diffedfrom10.pdf b/specs/oasis-2005xx-wss-soap-message-security-diffedfrom10.pdf
new file mode 100644
index 0000000..ed01be6
--- /dev/null
+++ b/specs/oasis-2005xx-wss-soap-message-security-diffedfrom10.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-username-token-profile-1.1-CD.pdf b/specs/oasis-2005xx-wss-username-token-profile-1.1-CD.pdf
new file mode 100644
index 0000000..cf1b9f9
--- /dev/null
+++ b/specs/oasis-2005xx-wss-username-token-profile-1.1-CD.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-username-token-profile-diffedfrom10.pdf b/specs/oasis-2005xx-wss-username-token-profile-diffedfrom10.pdf
new file mode 100644
index 0000000..0220461
--- /dev/null
+++ b/specs/oasis-2005xx-wss-username-token-profile-diffedfrom10.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-x509-token-profile-1.1-CD.pdf b/specs/oasis-2005xx-wss-x509-token-profile-1.1-CD.pdf
new file mode 100644
index 0000000..9b8c878
--- /dev/null
+++ b/specs/oasis-2005xx-wss-x509-token-profile-1.1-CD.pdf
Binary files differ
diff --git a/specs/oasis-2005xx-wss-x509-token-profile-diffedfrom10.pdf b/specs/oasis-2005xx-wss-x509-token-profile-diffedfrom10.pdf
new file mode 100644
index 0000000..342e8db
--- /dev/null
+++ b/specs/oasis-2005xx-wss-x509-token-profile-diffedfrom10.pdf
Binary files differ
diff --git a/specs/oasis-wss-rel-token-profile-1.1-draft02-cd.pdf b/specs/oasis-wss-rel-token-profile-1.1-draft02-cd.pdf
new file mode 100644
index 0000000..8b59a30
--- /dev/null
+++ b/specs/oasis-wss-rel-token-profile-1.1-draft02-cd.pdf
Binary files differ
diff --git a/specs/wss-11-interop-draft-01.doc b/specs/wss-11-interop-draft-01.doc
new file mode 100644
index 0000000..d186e33
--- /dev/null
+++ b/specs/wss-11-interop-draft-01.doc
Binary files differ
diff --git a/specs/wss-interop1-draft-06.pdf b/specs/wss-interop1-draft-06.pdf
new file mode 100644
index 0000000..3fe7d3d
--- /dev/null
+++ b/specs/wss-interop1-draft-06.pdf
Binary files differ
diff --git a/specs/wss-interop2-draft-06.pdf b/specs/wss-interop2-draft-06.pdf
new file mode 100644
index 0000000..875c5d4
--- /dev/null
+++ b/specs/wss-interop2-draft-06.pdf
Binary files differ
diff --git a/specs/wss-saml-interop1-draft-12.doc b/specs/wss-saml-interop1-draft-12.doc
new file mode 100644
index 0000000..40ec340
--- /dev/null
+++ b/specs/wss-saml-interop1-draft-12.doc
Binary files differ
diff --git a/specs/wss-saml2-interop-draft-v4.doc b/specs/wss-saml2-interop-draft-v4.doc
new file mode 100644
index 0000000..64573e2
--- /dev/null
+++ b/specs/wss-saml2-interop-draft-v4.doc
Binary files differ
diff --git a/specs/wss-swa-profile-1.1-draft-22.pdf b/specs/wss-swa-profile-1.1-draft-22.pdf
new file mode 100644
index 0000000..7d69679
--- /dev/null
+++ b/specs/wss-swa-profile-1.1-draft-22.pdf
Binary files differ
diff --git a/src/crypto.properties b/src/crypto.properties
new file mode 100644
index 0000000..9a18040
--- /dev/null
+++ b/src/crypto.properties
@@ -0,0 +1,6 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=pkcs12
+org.apache.ws.security.crypto.merlin.keystore.password=security
+org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458f-abf5-2f875f74882e
+org.apache.ws.security.crypto.merlin.alias.password=security
+org.apache.ws.security.crypto.merlin.file=keys/x509.PFX.MSFT
diff --git a/src/cryptoSKI.properties b/src/cryptoSKI.properties
new file mode 100644
index 0000000..014562c
--- /dev/null
+++ b/src/cryptoSKI.properties
@@ -0,0 +1,4 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=security
+org.apache.ws.security.crypto.merlin.file=keys/wss4j.keystore
diff --git a/src/log4j.properties b/src/log4j.properties
new file mode 100644
index 0000000..ff934a7
--- /dev/null
+++ b/src/log4j.properties
@@ -0,0 +1,74 @@
+# Set root category priority to INFO and its only appender to CONSOLE.
+log4j.rootCategory=FATAL, CONSOLE
+# log4j.rootCategory=DEBUG, LOGFILE
+
+# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
+# log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
+# log4j.logger.org.apache.axis.i18n.ProjectResourceBundle=INFO
+# log4j.logger.org.apache.ws.security.TIME=DEBUG
+# log4j.logger.org.apache.ws.security.message.EnvelopeIdResolver=DEBUG
+# log4j.logger.org.apache.ws.security.message.WSEncryptBody=INFO
+# log4j.logger.org.apache.ws.security.message.WSSignEnvelope=DEBUG
+# log4j.logger.org.apache.ws.security.processor.ReferenceListProcessor=DEBUG
+# log4j.logger.org.apache.ws.axis.security.WSDoAllSender=DEBUG
+# log4j.logger.org.apache.ws.axis.security.WSDoAllReceiver=DEBUG
+# log4j.logger.org.apache.ws.security.transform.STRTransform=DEBUG
+# log4j.logger.org.apache.ws.security.WSSecurityEngine=DEBUG
+# log4j.logger.org.apache.ws.security.WSSConfig=DEBUG
+# log4j.logger.org.apache.ws.security.message.token.SecurityTokenReference=DEBUG
+# log4j.logger.org.apache.ws.security.components.crypto.Merlin=DEBUG
+# log4j.logger.org.apache.xml.security.encryption.XMLCipher=DEBUG
+# log4j.logger.org.apache.xml.security.algorithms.SignatureAlgorithm=INFO
+# log4j.logger.org.apache.xml.security.signature.XMLSignature=DEBUG
+# log4j.logger.org.apache.xml.security.Init=INFO
+# log4j.logger.org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory=INFO
+# log4j.logger.org.apache.axis.i18n.ProjectResourceBundle=INFO
+# log4j.logger.org.apache.axis.utils.NSStack=INFO
+# log4j.logger.org.apache.axis.encoding.SerializationContextImpl=INFO
+# log4j.logger.org.apache.axis.encoding.DeserializationContextImpl=INFO
+# log4j.logger.org.apache.xml.security.signature.Reference=DEBUG
+# log4j.logger.wssec.TestWSSecurity=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew=DEBUG
+# log4j.logger.wssec.TestWSSecurity1=DEBUG
+# log4j.logger.wssec.TestWSSecurity2=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew2=DEBUG
+# log4j.logger.wssec.TestWSSecurity3=DEBUG
+# log4j.logger.wssec.TestWSSecurity4=DEBUG
+# log4j.logger.wssec.TestWSSecurity5=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew5=DEBUG
+# log4j.logger.wssec.TestWSSecurity6=DEBUG
+# log4j.logger.wssec.TestWSSecurity7=DEBUG
+# log4j.logger.wssec.TestWSSecurity8=DEBUG
+# log4j.logger.wssec.TestWSSecurity9=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew9=DEBUG
+# log4j.logger.wssec.TestWSSecurity10=DEBUG
+# log4j.logger.wssec.TestWSSecurity11=DEBUG
+# log4j.logger.wssec.TestWSSecurity12=DEBUG
+# log4j.logger.wssec.TestWSSecurity13=DEBUG
+# log4j.logger.wssec.TestWSSecurity14=DEBUG
+# log4j.logger.wssec.TestWSSecurityNew15=DEBUG
+# log4j.logger.wssec.TestWSSecurityST1=DEBUG
+# log4j.logger.wssec.TestWSSecurityNewST1=DEBUG
+# log4j.logger.wssec.TestWSSecurityST2=DEBUG
+# log4j.logger.wssec.TestWSSecurityNewST2=DEBUG
+# log4j.logger.wssec.TestWSSecurityST3=DEBUG
+# log4j.logger.wssec.TestWSSecurityNewST3=DEBUG
+# log4j.logger.wssec.TestWSSecuritySOAP12=DEBUG
+# log4j.logger.org.apache.ws.security.handler.WSS4JHandler=DEBUG
+# log4j.logger.org.apache.ws.security.handler.WSHandler=DEBUG
+log4j.logger.policy.WSSPolicyTesterAsymm=DEBUG
+log4j.logger.org.apache.ws.security.policy.parser.WSSPolicyProcessor=ERROR
+
+# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.Threshold=DEBUG
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n
+
+# LOGFILE is set to be a File appender using a PatternLayout.
+log4j.appender.LOGFILE=org.apache.log4j.FileAppender
+log4j.appender.LOGFILE.File=axis.log
+log4j.appender.LOGFILE.Append=true
+log4j.appender.LOGFILE.Threshold=DEBUG
+log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
diff --git a/src/org/apache/ws/axis/security/WSDoAllReceiver.java b/src/org/apache/ws/axis/security/WSDoAllReceiver.java
new file mode 100644
index 0000000..075b7ff
--- /dev/null
+++ b/src/org/apache/ws/axis/security/WSDoAllReceiver.java
@@ -0,0 +1,356 @@
+/*
+* Copyright  2003-2005 The Apache Software Foundation.
+*
+*  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.apache.ws.axis.security;
+
+/**
+ * @author Werner Dittmann (werner@apache.org)
+ *
+ */
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.axis.security.handler.WSDoAllHandler;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import java.io.ByteArrayOutputStream;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class WSDoAllReceiver extends WSDoAllHandler {
+
+    protected static Log log = LogFactory.getLog(WSDoAllReceiver.class.getName());
+    private static Log tlog =
+        LogFactory.getLog("org.apache.ws.security.TIME");
+
+    /**
+     * Axis calls invoke to handle a message.
+     * <p/>
+     *
+     * @param msgContext message context.
+     * @throws AxisFault
+     */
+    public void invoke(MessageContext msgContext) throws AxisFault {
+
+    	boolean doDebug = log.isDebugEnabled();
+
+        if (doDebug) {
+            log.debug("WSDoAllReceiver: enter invoke() with msg type: "
+                    + msgContext.getCurrentMessage().getMessageType());
+        }
+        long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }        
+
+        RequestData reqData = new RequestData();
+        /*
+        * The overall try, just to have a finally at the end to perform some
+        * housekeeping.
+        */
+        try {
+            reqData.setMsgContext(msgContext);
+
+            Vector actions = new Vector();
+            String action = null;
+            if ((action = (String) getOption(WSHandlerConstants.ACTION)) == null) {
+                action = (String) msgContext
+                        .getProperty(WSHandlerConstants.ACTION);
+            }
+            if (action == null) {
+                throw new AxisFault("WSDoAllReceiver: No action defined");
+            }
+            int doAction = WSSecurityUtil.decodeAction(action, actions);
+
+            String actor = (String) getOption(WSHandlerConstants.ACTOR);
+
+            Message sm = msgContext.getCurrentMessage();
+            Document doc = null;
+
+            /**
+             * We did not receive anything...Usually happens when we get a
+             * HTTP 202 message (with no content)
+             */
+            if(sm == null){
+                return;
+            }
+
+            try {
+                doc = sm.getSOAPEnvelope().getAsDocument();
+                if (doDebug) {
+                    log.debug("Received SOAP request: ");
+                    log.debug(org.apache.axis.utils.XMLUtils
+                            .PrettyDocumentToString(doc));
+                }
+            } catch (Exception ex) {
+                throw new AxisFault(
+                        "WSDoAllReceiver: cannot convert into document", ex);
+            }
+            /*
+            * Check if it's a response and if its a fault. Don't process
+            * faults.
+            */
+            String msgType = sm.getMessageType();
+            if (msgType != null && msgType.equals(Message.RESPONSE)) {
+                SOAPConstants soapConstants = WSSecurityUtil
+                        .getSOAPConstants(doc.getDocumentElement());
+                if (WSSecurityUtil.findElement(doc.getDocumentElement(),
+                        "Fault", soapConstants.getEnvelopeURI()) != null) {
+                    return;
+                }
+            }
+
+            /*
+            * To check a UsernameToken or to decrypt an encrypted message we
+            * need a password.
+            */
+            CallbackHandler cbHandler = null;
+            if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
+                cbHandler = getPasswordCB(reqData);
+            }
+
+            /*
+            * Get and check the Signature specific parameters first because
+            * they may be used for encryption too.
+            */
+            doReceiverAction(doAction, reqData);
+            
+            Vector wsResult = null;
+            if (tlog.isDebugEnabled()) {
+                t1 = System.currentTimeMillis();
+            }        
+
+            try {
+                wsResult = secEngine.processSecurityHeader(doc, actor,
+                        cbHandler, reqData.getSigCrypto(), reqData.getDecCrypto());
+            } catch (WSSecurityException ex) {
+                ex.printStackTrace();
+                throw new AxisFault(
+                        "WSDoAllReceiver: security processing failed", ex);
+            }
+
+            if (tlog.isDebugEnabled()) {
+                t2 = System.currentTimeMillis();
+            }        
+
+            if (wsResult == null) { // no security header found
+                if (doAction == WSConstants.NO_SECURITY) {
+                    return;
+                } else {
+                    throw new AxisFault(
+                            "WSDoAllReceiver: Request does not contain required Security header");
+                }
+            }
+
+            if (reqData.getWssConfig().isEnableSignatureConfirmation() && msgContext.getPastPivot()) {
+                checkSignatureConfirmation(reqData, wsResult);
+            }
+            /*
+            * save the processed-header flags
+            */
+            ArrayList processedHeaders = new ArrayList();
+            Iterator iterator = sm.getSOAPEnvelope().getHeaders().iterator();
+            while (iterator.hasNext()) {
+                org.apache.axis.message.SOAPHeaderElement tempHeader = (org.apache.axis.message.SOAPHeaderElement) iterator
+                        .next();
+                if (tempHeader.isProcessed()) {
+                    processedHeaders.add(tempHeader.getQName());
+                }
+            }
+
+            /*
+            * If we had some security processing, get the original SOAP part of
+            * Axis' message and replace it with new SOAP part. This new part
+            * may contain decrypted elements.
+            */
+            SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
+
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(doc, os, true);
+            sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
+            if (doDebug) {
+                log.debug("Processed received SOAP request");
+                log.debug(org.apache.axis.utils.XMLUtils
+                        .PrettyDocumentToString(doc));
+            }
+            if (tlog.isDebugEnabled()) {
+                t3 = System.currentTimeMillis();
+            }        
+
+            /*
+            * set the original processed-header flags
+            */
+            iterator = processedHeaders.iterator();
+            while (iterator.hasNext()) {
+                QName qname = (QName) iterator.next();
+                Enumeration headersByName = sm.getSOAPEnvelope().getHeadersByName(
+                        qname.getNamespaceURI(), qname.getLocalPart());
+                while (headersByName.hasMoreElements()) {
+                    org.apache.axis.message.SOAPHeaderElement tempHeader =
+                        (org.apache.axis.message.SOAPHeaderElement) headersByName.nextElement();
+                    tempHeader.setProcessed(true);
+                }
+            }
+
+            /*
+            * After setting the new current message, probably modified because
+            * of decryption, we need to locate the security header. That is, we
+            * force Axis (with getSOAPEnvelope()) to parse the string, build
+            * the new header. Then we examine, look up the security header and
+            * set the header as processed.
+            *
+            * Please note: find all header elements that contain the same actor
+            * that was given to processSecurityHeader(). Then check if there is
+            * a security header with this actor.
+            */
+
+            SOAPHeader sHeader = null;
+            try {
+                sHeader = sm.getSOAPEnvelope().getHeader();
+            } catch (Exception ex) {
+                throw new AxisFault(
+                        "WSDoAllReceiver: cannot get SOAP header after security processing",
+                        ex);
+            }
+
+            Iterator headers = sHeader.examineHeaderElements(actor);
+
+            SOAPHeaderElement headerElement = null;
+            while (headers.hasNext()) {
+                org.apache.axis.message.SOAPHeaderElement hE = (org.apache.axis.message.SOAPHeaderElement) headers.next();
+                if (hE.getLocalName().equals(WSConstants.WSSE_LN)
+                        && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
+                    headerElement = hE;
+                    break;
+                }
+            }
+            ((org.apache.axis.message.SOAPHeaderElement) headerElement)
+                    .setProcessed(true);
+
+            /*
+            * Now we can check the certificate used to sign the message. In the
+            * following implementation the certificate is only trusted if
+            * either it itself or the certificate of the issuer is installed in
+            * the keystore.
+            *
+            * Note: the method verifyTrust(X509Certificate) allows custom
+            * implementations with other validation algorithms for subclasses.
+            */
+
+            // Extract the signature action result from the action vector
+            WSSecurityEngineResult actionResult = WSSecurityUtil
+                    .fetchActionResult(wsResult, WSConstants.SIGN);
+
+            if (actionResult != null) {
+                X509Certificate returnCert = actionResult.getCertificate();
+
+                if (returnCert != null) {
+                    if (!verifyTrust(returnCert, reqData)) {
+                        throw new AxisFault(
+                                "WSDoAllReceiver: The certificate used for the signature is not trusted");
+                    }
+                }
+            }
+
+            /*
+            * Perform further checks on the timestamp that was transmitted in
+            * the header. In the following implementation the timestamp is
+            * valid if it was created after (now-ttl), where ttl is set on
+            * server side, not by the client.
+            *
+            * Note: the method verifyTimestamp(Timestamp) allows custom
+            * implementations with other validation algorithms for subclasses.
+            */
+
+            // Extract the timestamp action result from the action vector
+            actionResult = WSSecurityUtil.fetchActionResult(wsResult,
+                    WSConstants.TS);
+
+            if (actionResult != null) {
+                Timestamp timestamp = actionResult.getTimestamp();
+
+                if (timestamp != null) {
+                    if (!verifyTimestamp(timestamp, decodeTimeToLive(reqData))) {
+                        throw new AxisFault(
+                                "WSDoAllReceiver: The timestamp could not be validated");
+                    }
+                }
+            }
+
+            /*
+            * now check the security actions: do they match, in right order?
+            */
+            if (!checkReceiverResults(wsResult, actions)) {
+                throw new AxisFault(
+                    "WSDoAllReceiver: security processing failed (actions mismatch)");                
+                
+            }
+            /*
+            * All ok up to this point. Now construct and setup the security
+            * result structure. The service may fetch this and check it.
+            */
+            Vector results = null;
+            if ((results = (Vector) msgContext
+                    .getProperty(WSHandlerConstants.RECV_RESULTS)) == null) {
+                results = new Vector();
+                msgContext
+                        .setProperty(WSHandlerConstants.RECV_RESULTS, results);
+            }
+            WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
+            results.add(0, rResult);
+            if (tlog.isDebugEnabled()) {
+                t4 = System.currentTimeMillis();
+                tlog.debug("Receive request: total= " + (t4 - t0) +
+                        " request preparation= " + (t1 - t0) +
+                        " request processing= " + (t2 - t1) +
+                        " request to Axis= " + (t3 - t2) + 
+                        " header, cert verify, timestamp= " + (t4 - t3) +
+                        "\n");                                
+            }        
+
+            if (doDebug) {
+                log.debug("WSDoAllReceiver: exit invoke()");
+            }
+        } catch (WSSecurityException e) {
+            throw new AxisFault(e.getMessage(), e);
+        } finally {
+            reqData.clear();
+            reqData = null;
+        }
+    }
+}
diff --git a/src/org/apache/ws/axis/security/WSDoAllSender.java b/src/org/apache/ws/axis/security/WSDoAllSender.java
new file mode 100644
index 0000000..a8fa572
--- /dev/null
+++ b/src/org/apache/ws/axis/security/WSDoAllSender.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.axis.security;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.axis.security.handler.WSDoAllHandler;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Vector;
+
+/**
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public class WSDoAllSender extends WSDoAllHandler {
+
+    protected static Log log = LogFactory.getLog(WSDoAllSender.class.getName());
+    private static Log tlog =
+        LogFactory.getLog("org.apache.ws.security.TIME");
+    
+    /**
+     * Axis calls invoke to handle a message. <p/>
+     *
+     * @param mc message context.
+     * @throws AxisFault
+     */
+    public void invoke(MessageContext mc) throws AxisFault {
+
+        boolean doDebug = log.isDebugEnabled();
+        
+        long t0 = 0, t1 = 0, t2 = 0, t3 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+
+        if (doDebug && mc.getCurrentMessage() != null
+                && mc.getCurrentMessage().getMessageType() != null) {
+            log.debug("WSDoAllSender: enter invoke() with msg type: "
+                    + mc.getCurrentMessage().getMessageType());
+        }
+
+        RequestData reqData = new RequestData();
+
+        reqData.setMsgContext(mc);
+        /*
+	 * The overall try, just to have a finally at the end to perform some
+	 * housekeeping.
+	 */
+        try {
+            /*
+	     * Get the action first.
+	     */
+            Vector actions = new Vector();
+	    String action = getString(WSHandlerConstants.ACTION, mc);
+            if (action == null) {
+                throw new AxisFault("WSDoAllSender: No action defined");
+            }
+            int doAction = WSSecurityUtil.decodeAction(action, actions);
+            if (doAction == WSConstants.NO_SECURITY) {
+                return;
+            }
+
+            /*
+                * For every action we need a username, so get this now. The
+                * username defined in the deployment descriptor takes precedence.
+                */
+            reqData.setUsername((String) getOption(WSHandlerConstants.USER));
+            if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+                String username = (String) getProperty(reqData.getMsgContext(), WSHandlerConstants.USER);
+                if (username != null) {
+                    reqData.setUsername(username);
+                } else {
+                    reqData.setUsername(((MessageContext)reqData.getMsgContext()).getUsername());
+                    ((MessageContext)reqData.getMsgContext()).setUsername(null);
+                }
+            }
+            /*
+                * Now we perform some set-up for UsernameToken and Signature
+                * functions. No need to do it for encryption only. Check if
+                * username is available and then get a passowrd.
+                */
+            if ((doAction & (WSConstants.SIGN | WSConstants.UT | WSConstants.UT_SIGN)) != 0) {
+                /*
+                     * We need a username - if none throw an AxisFault. For
+                     * encryption there is a specific parameter to get a username.
+                     */
+                if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+                    throw new AxisFault(
+                            "WSDoAllSender: Empty username for specified action");
+                }
+            }
+            if (doDebug) {
+                log.debug("Action: " + doAction);
+                log.debug("Actor: " + reqData.getActor());
+            }
+            /*
+                * Now get the SOAP part from the request message and convert it
+                * into a Document.
+                *
+                * This forces Axis to serialize the SOAP request into FORM_STRING.
+                * This string is converted into a document.
+                *
+                * During the FORM_STRING serialization Axis performs multi-ref of
+                * complex data types (if requested), generates and inserts
+                * references for attachements and so on. The resulting Document
+                * MUST be the complete and final SOAP request as Axis would send it
+                * over the wire. Therefore this must shall be the last (or only)
+                * handler in a chain.
+                *
+                * Now we can perform our security operations on this request.
+                */
+            Document doc = null;
+            Message message = mc.getCurrentMessage();
+
+            /**
+             * There is nothing to send...Usually happens when the provider needs to
+             * send a HTTP 202 message (with no content)
+             */
+            if(message == null){
+                return;
+            }
+
+            /*
+            * If the message context property conatins a document then this is
+            * a chained handler.
+            */
+            SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();
+            if ((doc = (Document) ((MessageContext)reqData.getMsgContext())
+                    .getProperty(WSHandlerConstants.SND_SECURITY)) == null) {
+                try {
+                    doc = ((org.apache.axis.message.SOAPEnvelope) sPart
+                            .getEnvelope()).getAsDocument();
+                } catch (Exception e) {
+                    throw new AxisFault(
+                            "WSDoAllSender: cannot get SOAP envlope from message"
+                                    + e);
+                }
+            }
+            if (tlog.isDebugEnabled()) {
+                t1 = System.currentTimeMillis();
+            }
+
+            doSenderAction(doAction, doc, reqData, actions, !mc.getPastPivot());
+            
+            if (tlog.isDebugEnabled()) {
+                t2 = System.currentTimeMillis();
+            }
+
+            /*
+                * If required convert the resulting document into a message first.
+                * The outputDOM() method performs the necessary c14n call. After
+                * that we extract it as a string for further processing.
+                *
+                * Set the resulting byte array as the new SOAP message.
+                *
+                * If noSerialization is false, this handler shall be the last (or
+                * only) one in a handler chain. If noSerialization is true, just
+                * set the processed Document in the transfer property. The next
+                * Axis WSS4J handler takes it and performs additional security
+                * processing steps.
+                *
+                */
+            if (reqData.isNoSerialization()) {
+                ((MessageContext)reqData.getMsgContext()).setProperty(WSHandlerConstants.SND_SECURITY,
+                        doc);
+            } else {
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                XMLUtils.outputDOM(doc, os, true);
+                sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
+                if (doDebug) {
+                    String osStr = null;
+                    try {
+                        osStr = os.toString("UTF-8");
+                    } catch (UnsupportedEncodingException e) {
+                        osStr = os.toString();
+                    }
+                    log.debug("Send request:");
+                    log.debug(osStr);
+                }
+                ((MessageContext)reqData.getMsgContext()).setProperty(WSHandlerConstants.SND_SECURITY,
+                        null);
+            }
+            if (tlog.isDebugEnabled()) {
+                t3 = System.currentTimeMillis();
+                tlog.debug("Send request: total= " + (t3 - t0) +
+                        " request preparation= " + (t1 - t0) +
+                        " request processing= " + (t2 - t1) +
+                        " request to Axis= " + (t3 - t2) +
+                        "\n");                
+            }
+
+            if (doDebug) {
+                log.debug("WSDoAllSender: exit invoke()");
+            }
+        } catch (WSSecurityException e) {
+            throw new AxisFault(e.getMessage(), e);
+        } finally {
+            reqData.clear();
+            reqData = null;
+        }
+    }
+}
diff --git a/src/org/apache/ws/axis/security/handler/WSDoAllHandler.java b/src/org/apache/ws/axis/security/handler/WSDoAllHandler.java
new file mode 100644
index 0000000..b0f3168
--- /dev/null
+++ b/src/org/apache/ws/axis/security/handler/WSDoAllHandler.java
@@ -0,0 +1,200 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.axis.security.handler;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Handler;
+import org.apache.axis.MessageContext;
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.axis.utils.LockableHashtable;
+import org.apache.commons.logging.Log;
+import org.apache.ws.security.handler.WSHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+
+/**
+ * <code>WSDoAllHandler</code> is a utility class which implements simple
+ * property setting/getting behavior, and stubs out a lot of the Handler
+ * methods.  Extend this class to make writing your Handlers easier, and
+ * then override what you need to.
+ */
+public abstract class WSDoAllHandler extends WSHandler implements Handler {
+    private static Log log =
+            LogFactory.getLog(WSDoAllHandler.class.getName());
+
+    protected boolean makeLockable = false;
+    protected Hashtable options;
+    protected String name;
+
+    /**
+     * Should this Handler use a LockableHashtable for options?
+     * Default is 'false'.
+     */
+    protected void setOptionsLockable(boolean makeLockable) {
+        this.makeLockable = makeLockable;
+    }
+
+    protected void initHashtable() {
+        if (makeLockable) {
+            options = new LockableHashtable();
+        } else {
+            options = new Hashtable();
+        }
+    }
+
+    /**
+     * Stubbed-out methods.  Override in your child class to implement
+     * any real behavior.  Note that there is NOT a stub for invoke(), since
+     * we require any Handler derivative to implement that.
+     */
+    public void init() {
+    }
+
+    public void cleanup() {
+    }
+
+    public boolean canHandleBlock(QName qname) {
+        return false;
+    }
+
+    public void onFault(MessageContext msgContext) {
+    }
+
+    /**
+     * Set the given option (name/value) in this handler's bag of options
+     */
+    public void setOption(String name, Object value) {
+        if (options == null) initHashtable();
+        options.put(name, value);
+    }
+
+    /**
+     * Set a default value for the given option:
+     * if the option is not already set, then set it.
+     * if the option is already set, then do not set it.
+     * <p/>
+     * If this is called multiple times, the first with a non-null value
+     * if 'value' will set the default, remaining calls will be ignored.
+     * <p/>
+     * Returns true if value set (by this call), otherwise false;
+     */
+    public boolean setOptionDefault(String name, Object value) {
+        boolean val = (options == null || options.get(name) == null) && value != null;
+        if (val) {
+            setOption(name, value);
+        }
+        return val;
+    }
+
+    /**
+     * Returns the option corresponding to <code>name</code>.
+     *
+     * @param name the non-null name of the option.
+     * @return the option on <code>name</code> if <code>name</code>
+     *  exists; otherwise null.
+     */
+    public Object getOption(String name) {
+	if (name == null) {
+	    throw new IllegalArgumentException("name cannot be null");
+	}
+        if (options == null) {
+	    return null;
+	}
+        return options.get(name);
+    }
+
+    /**
+     * Return the entire list of options
+     */
+    public Hashtable getOptions() {
+        return (options);
+    }
+
+    public void setOptions(Hashtable opts) {
+        options = opts;
+    }
+
+    /**
+     * Set the name (i.e. registry key) of this Handler
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Return the name (i.e. registry key) for this Handler
+     */
+    public String getName() {
+        return name;
+    }
+
+    public Element getDeploymentData(Document doc) {
+        log.debug("Enter: BasicHandler::getDeploymentData");
+
+        Element root = doc.createElementNS("", "handler");
+
+        root.setAttribute("class", this.getClass().getName());
+        options = this.getOptions();
+        if (options != null) {
+            Enumeration e = options.keys();
+            while (e.hasMoreElements()) {
+                String k = (String) e.nextElement();
+                Object v = options.get(k);
+                Element e1 = doc.createElementNS("", "option");
+                e1.setAttribute("name", k);
+                e1.setAttribute("value", v.toString());
+                root.appendChild(e1);
+            }
+        }
+        log.debug("Exit: WSDoAllHandler::getDeploymentData");
+        return (root);
+    }
+
+    public void generateWSDL(MessageContext msgContext) throws AxisFault {
+    }
+
+    /**
+     * Return a list of QNames which this Handler understands.  By returning
+     * a particular QName here, we are committing to fulfilling any contracts
+     * defined in the specification of the SOAP header with that QName.
+     */
+    public List getUnderstoodHeaders() {
+        return null;
+    }
+
+    public Object getProperty(Object msgContext, String key) {
+        return ((MessageContext)msgContext).getProperty(key);
+    }
+    
+    public void setProperty(Object msgContext, String key, Object value) {
+        ((MessageContext)msgContext).setProperty(key, value);
+    }
+
+    public String getPassword(Object msgContext) {
+        return ((MessageContext)msgContext).getPassword();
+    }
+
+    public void setPassword(Object msgContext, String password) {
+        ((MessageContext)msgContext).setPassword(password);
+    }
+}
diff --git a/src/org/apache/ws/axis/security/package.html b/src/org/apache/ws/axis/security/package.html
new file mode 100644
index 0000000..0fd3be2
--- /dev/null
+++ b/src/org/apache/ws/axis/security/package.html
@@ -0,0 +1,680 @@
+<!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  -->
+<html>
+<head>
+  <title>Axis handler for WSS4J</title>
+<!--
+
+  @(#)Axis handler for WSS4J 
+
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes and interfaces that implement WSS4J Axis handlers.
+These handler process SOAP requests according to the OASIS Web Service 
+Security (WSS) specifications.
+<p/>
+The WSS4J Axis handlers <code>WSDoAllSender</code> and <code>WSDoAllReceiver
+</code> control the creation and consumption of secure SOAP requests.
+The handlers work behind the scenes and are usually transparent to Web Service
+(WS) applications. The Axis deployment descriptor files (*.wsdd) may contain all
+necessary information to control the security processing.
+<p/>
+A WS application may also set properties to control the handlers
+and provide default values. If the deployment descriptor sets the same 
+property (parameter) then the deployment descriptor overwrites the application
+defined property.  Thus, deployment settings overwrite application settings 
+to fulfill site specific requirements.
+
+<h3>Prerequisties</h3>
+The WS Security Axis handlers use the WSS4J classes (Web Service Security 
+for Java) to process the SOAP messages. WSS4J in turn uses the Apache XML Security 
+project to handle XML Security according to XML Signature and XML Encryption. 
+
+<ul>
+  <li><a href="http://ws.apache.org/ws-fx/wss4j/index.html">WSS4J</a></li>
+  <li><a href="http://xml.apache.org/security/index.html">XML Security</a></li>
+</ul>
+
+The WSS4J Axis handlers require Axis V1.2 because of some problems in previous
+Axis versions. WSS4J CVS contains the latest Axis libraries. 
+
+<h3>Related Documentation</h3>
+The OASIS WSS specifications define a number of features and it is possible 
+to combine them in several ways. The WSS4J Axis handlers already support 
+a large number of WSS features and their combinations. 
+<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss">
+Here</a> are the WSS specifications.
+
+<h3>The basics - a simple example that uses <code>UsernameToken</code></h3>
+This chapter gives an overview and some examples how to deploy 
+the WSS4J Axis handlers and how the parameters and their values control the
+handlers. For a better understanding of this chapter the reader shall 
+have a knowledge of the OASIS WSS specifications.
+<p/>
+The {@link org.apache.ws.security.handler.WSHandlerConstants}, 
+{@link org.apache.ws.axis.security.WSDoAllSender}, and 
+{@link org.apache.ws.axis.security.WSDoAllReceiver}
+provide additional and detailed documentation.
+
+<h4>Axis deployment descriptor to insert a <code>UsernameToken</code></h4>
+The following snippet shows a general layout how to deploy a WS Axis handler
+on the client (application) side.
+<pre>
+ &lt;!-- define the service, use the WSDoAllSender security handler in request flow -->
+ &lt;service name="Ping1">
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    &lt;parameter name="action" value="UsernameToken"/>
+    &lt;parameter name="user" value="werner"/>
+    &lt;parameter name="passwordType" value="PasswordText" />
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/>
+   &lt;/handler>
+  &lt;/requestFlow>
+  &lt;/service>
+</pre>
+
+This is the standard way to deploy an Axis handler. Axis parses the deployment
+descriptor and provides the parameters and their value to the handler. Each
+service can have its own request and response flow definition, which provides
+a very flexible set-up of the security parameters.
+<p/>
+The above setup inserts the most simple security structure into a SOAP request: 
+the simple <code>UsernameToken</code>. This token includes a username and the 
+according password. Both fields are sent in cleartext, thus it provides no 
+real security.
+<p/>
+
+The parameters and their meanings are:
+<ul>
+<li><code>action</code> defines the security action. The value <code>
+    UsernameToken</code> directs the handler to insert this token into
+    the SOAP request.
+</li>
+<li><code>user</code> specifies the username to include in the token.
+</li>
+<li><code>passwordType</code> is a pecific parameter for the <code>
+    UsernameToken</code> action and defines the encoding of the passowrd.
+    <code>PasswordText</code> specifies to send the password in
+    plain text, <code>PasswordDigest</code> specifies to send the
+    password in digest mode (refer to WSS UsernameToken Profile)
+</li>
+<li><code>passwordCallbackClass</code> contains the name of a class that
+    implements a method to get the user's password. Please refer to the
+    detailed documentation in 
+    {@link org.apache.ws.security.handler.WSHandlerConstants#PW_CALLBACK_CLASS}.
+    </li>
+</ul>
+The WSS4J Axis security handler interprets the parameter values and controls
+the WSS4J modules to generate the following SOAP request:
+<pre>
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  &lt;soapenv:Header>
+    &lt;wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext" 
+      soapenv:mustUnderstand="true">
+      &lt;wsse:UsernameToken>
+        &lt;wsse:Username>werner&lt;/wsse:Username>
+        &lt;wsse:Password Type="wsse:PasswordText">security&lt;/wsse:Password>
+      &lt;/wsse:UsernameToken>
+    &lt;/wsse:Security>
+  &lt;/soapenv:Header>
+  &lt;soapenv:Body>
+    &lt;Ping xmlns="http://xmlsoap.org/Ping">
+      &lt;text>Scenario 1 text&lt;/text>
+      &lt;ticket xmlns:ns1="http://xmlsoap.org/Ping" 
+        xsi:type="ns1:ticketType">scenario1&lt;/ticket>
+    &lt;/Ping>
+  &lt;/soapenv:Body>
+&lt;/soapenv:Envelope>
+</pre>
+This is a pretty print of the real SOAP message.
+
+<h4><a name="pwCallBackClass">The password callback class</a></h4>
+
+The deployment descriptor contains the user name that the handler inserts into
+the <code>UsernameToken</code> but not the password. In general it is not a
+good idea to store sensitive information like a password in cleartext. To
+get the password the WSS4J Axis handler uses a password callback
+technique similar to the JAAS mechansim. The parameter 
+<code>passwordCallbackClass</code> contains the classname of the callback
+class. This class must implement the
+{@link javax.security.auth.callback.CallbackHandler}
+interface. The WSS4J Axis handler gets this class,
+instantiates it, and calls the <code>handle</code> method when it
+needs a password. Refer also to the 
+{@link org.apache.ws.security.handler.WSHandlerConstants#PW_CALLBACK_CLASS
+ parameter} documentation.
+ <p/>
+ The following code snippet shows a simple password callback class:
+ <pre>
+package org.apache.ws.axis.oasis;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.ws.security.WSPasswordCallback;
+
+public class PWCallback implements CallbackHandler {
+
+  private static final byte[] key = {
+    (byte)0x31, (byte)0xfd, (byte)0xcb, (byte)0xda,
+    (byte)0xfb, (byte)0xcd, (byte)0x6b, (byte)0xa8,
+    (byte)0xe6, (byte)0x19, (byte)0xa7, (byte)0xbf,
+    (byte)0x51, (byte)0xf7, (byte)0xc7, (byte)0x3e,
+    (byte)0x80, (byte)0xae, (byte)0x98, (byte)0x51,
+    (byte)0xc8, (byte)0x51, (byte)0x34, (byte)0x04,
+  };
+	
+  public void handle(Callback[] callbacks)
+    throws IOException, UnsupportedCallbackException {
+    for (int i = 0; i &lt; callbacks.length; i++) {
+      if (callbacks[i] instanceof WSPasswordCallback) {
+        WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+        /*
+         * here call a function/method to lookup the password for
+         * the given identifier (e.g. a user name or keystore alias)
+         * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+         * for testing we supply a fixed name/fixed key here.
+         */
+        if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {
+          pc.setKey(key);
+        }
+        else {
+          pc.setPassword("security");
+        }
+      } else {
+        throw new UnsupportedCallbackException(
+          callbacks[i], "Unrecognized Callback");
+      }
+    }
+  }
+}
+</pre>
+The Java {@link javax.security.auth.callback.CallbackHandler callback} handler
+documentation provides a detailed description of the interface and exceptions.
+<p/>
+The WSS4J library uses a specific class to get the required password or key
+informations. The <code>WSSPasswordCallback</code> class implements the
+{@link javax.security.auth.callback.Callback} interface according to the
+JAAS. Depending on it usage this class either carries the required password
+as a Java <code>String </code> or it carries the required key information 
+as a Java <code>byte[]</code> array. Refer to
+{@link org.apache.ws.security.WSPasswordCallback} that contains a
+detailed description of the usage codes.
+<p/>
+The WSS4J Axis handler or the WSS4J modules set the usage code before
+they call <code>handle</code> method. 
+
+<h4>Application sets parameters to insert in <code>UsernameToken</code></h4>
+
+Sometimes it is not feasable or not possible to determine parameters
+and their values during deployment. In this case the application can
+set paramters during runtime. The WSS4J Axis handlers use the Axis
+<code>setProperty</code> method to support this feature.
+<p/>
+The following code snippet shows an example how to use the dynamic setting
+of parameters and their values:
+<pre>
+   ...
+ Service service = new Service();
+ Call call = (Call) service.createCall();
+   ...  
+ call.setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+ call.setProperty(WSHandlerConstants.USER, "werner");
+   ...
+</pre>
+Use this way if your application dynamically creates a <code>call</code> 
+object. If your application uses stubs generated by Axis' <code>WSDL2Java
+</code> tool, the application uses the following functions:
+<pre>
+    ...
+ PingServiceLocator service = new PingServiceLocator();
+    ...
+ PingPort port = (PingPort) service.getPing1();
+ port._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+ port._setProperty(WSHandlerConstants.USER, "werner");
+    ...
+</pre>
+Please note that <code>_setProperty</code> is a Axis specific call.
+
+<h4>The password callback object reference</h4>
+
+In addition to the <a href="#pwCallBackClass">password callback class</a>
+an application may set a password callback object using the <code>
+  setProperty()</code> methods. Only applications (and Axis handlers that
+  preceed the WSS4J Axis handlers in a handler chain) can use this feature.
+  <p/>
+  For example:
+  <pre>
+public class Scenario1 implements CallbackHandler {
+
+  public static void main(String args[]) {
+    ...
+    PingServiceLocator service = new PingServiceLocator();
+    ...
+    PingPort port = (PingPort) service.getPing1();
+    ((org.apache.axis.client.Stub)port)._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+    ((org.apache.axis.client.Stub)port._setProperty(WSHandlerConstants.USER, "werner");
+    ((org.apache.axis.client.Stub)port._setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
+    ...
+  }
+
+  public void handle(Callback[] callbacks) {
+    ...
+  }
+}
+</pre>
+
+<h4>Deployment of the WSS4J Axis <code>WSDoAllReceiver</code> handler</h4>
+
+Similar to the deployment descriptor of the sending handler <code>WSDoAllSender
+</code> a deployment descriptor for the receiving handler exists. For the above
+example the deployment descriptor look like:
+<pre>
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="action" value="UsernameToken"/>
+   &lt;/handler>
+  &lt;/requestFlow>
+</pre>
+The receiving WSS4J Axis handler checks if the SOAP request matches the defined
+actions.
+
+<h3>Combining security actions</h3>
+
+Often it is necessary to combine or concatenate several security actions, for 
+example to encrypt parts of a message and sign some other parts. The WSS4J 
+Axis handlers provide easy and simple methods to combine or concatenate
+security actions. 
+<p/>
+This chapter describes simple combinations of actions.
+
+<h4>Combine <code>UsernameToken</code> and <code>Encryption</code></h4>
+
+The WS Interoperability specifications define this use case: 
+<ul>
+  <li>Insert a <code>UsernameToken</code>, use <code>PasswordText</code>
+    to set the password. In addition add a timestamp and a nonce into
+    the <code>UsernameToken</code></li>
+  <li>Encrypt the <code>UsernameToken</code> to protect the information.
+    </li>
+</ul>
+
+The Axis deplyment descriptor for this use case:
+<pre>
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    &lt;parameter name="action" value="UsernameToken Encrypt"/>
+    &lt;parameter name="user" value="werner"/>
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="passwordType" value="PasswordText" />
+    &lt;parameter name="addUTElement" value="Nonce Created" />
+    &lt;parameter name="encryptionPropFile" value="crypto.properties" />
+    &lt;parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" />
+    &lt;parameter name="encryptionUser" 
+      value="16c73ab6-b892-458f-abf5-2f875f74882e" />
+    &lt;parameter name="encryptionParts" 
+      value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken" />  
+   &lt;/handler>
+  &lt;/requestFlow>  
+</pre>
+
+This descriptor contains some new parameters to control the <code>UsernameToken
+</code> element and its encryption. The new parameters and their meaning are:
+<ul>
+  <li><code>addUTElement</code> - controls if the handler shall insert elements
+    into the <code>UsernameToken</code>. The value is a blank separated list of
+    element names to include. Only <code>Nonce</code> and <code>Created</code> are
+    supported.</li>
+  <li><code>encryptionPropFile</code> - the name of a crypto property file. This
+    file contains parameters and property that control the encryption. Please refer
+    to the
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_PROP_FILE 
+    detailed} description of the cyrpto property file.</li>
+  <li><code>encryptionKeyIdentifier</code> - specifies the format in which the 
+    handler inserts the encryption key into the SOAP request. Please refer
+    to the 
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_KEY_ID 
+    detailed} description.</li>
+  <li><code>encryptionUser</code> - the name or identifier of the user who owns
+    the public key to encrypt the data. Usually this is the name or alias name
+    of the owner's certificate in a keystore.</li>
+  <li><code>encryptionParts</code> - controls which part or parts the handler
+    of the SOAP shall encrypt. If this parameter is not defined, WSS4J encrypts
+    the whole SOAP Body in <code>Content</code> mode. The value of the
+    parameter in this example specifies to encrypt the element <code>
+    UsernameToken</code>, contained in the namespace
+    <code>http://schemas.xmlsoap.org/ws/2002/07/secext</code>. The encryption
+    module uses the <code>Element</code> mode to encrypt the element data.
+    Please refer to the
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENCRYPTION_PARTS 
+    detailed} description.
+    </li>
+</ul>
+The matching receiver deployment descriptor:
+<pre>
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="action" value="UsernameToken Encrypt"/>
+    &lt;parameter name="decryptionPropFile" value="crypto.properties" />
+   &lt;/handler>
+  &lt;/requestFlow>
+</pre>
+The only new parameter here is the <code>decryptionPropFile</code>. This
+parameter defines the crypto property file at the receiver side. The value
+  of the <code>action</code> parameter matches the according value at the
+  sender side. The WSS4J Axis receiver checks if the SOAP request contains
+  the required security data.
+
+<h4>Combine Signature and Encryption</h4>
+
+This is a very common usage of Web Service security. The WSS4J Axis handler
+provides flexible parameter settings that support several ways to use
+the Signature/Encryption combination.
+<p/>
+A WSS4J Axis deployment descriptor for a simple Singature/Encryption of
+SOAP requests:
+<pre>
+&lt;requestFlow>
+  &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    &lt;parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/>
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="action" value="Signature Encrypt"/>
+    &lt;parameter name="signaturePropFile" value="crypto.properties" />
+  &lt;/handler>
+&lt;/requestFlow>
+</pre>
+This simple deployment descriptor signs and encrypts the SOAP Body part.
+The only new parameter, <code>signaturePropFile</code>, specifies the
+name of the signature crypto property file to use. Because no 
+<code>encryptionPropFile</code> is declared the handler also uses the signature
+property file to get the encryption certificate. The same holds true for
+the username. The password callback class must return a password
+to get the user's private key (the keystore is defined in the crypto
+property file) that WSS4J uses to generate the signature. The encryption
+method uses the user's public key to encrypt the dynamically generated
+session key.
+<p/>
+The <code>action</code> parameter defines <code>Signature Encryption</code>.
+Thus the handler first signs, then the encrypts the data.
+Because the deployment descriptor does not contain specific encryption or 
+signature part parameters, WSS4J defaults to the data of the SOAP Body element.
+<p/>
+Also all other parameters use their default setting, such as the format of the
+key identifiers, encryption modifiers, and so on. Please refer to the
+{@link org.apache.ws.security.handler.WSHandlerConstants detailed}
+documentation of the parameters.
+<p/>
+If the WSS4J Axis handler shall perform encryption only, then the
+deployment descriptor must contain the encryption specific parameters. Only
+if sign <b>and</b> encryption is required the encryption method falls back to
+the signature parameters if the encryption specific parameters are not set.
+<p/>
+The matching receiver deployment descriptor is also very simple:
+<pre>
+&lt;requestFlow>
+  &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="action" value="Signature Encrypt"/>
+    &lt;parameter name="signaturePropFile" value="crypto.properties" />
+  &lt;/handler>
+ &lt;/requestFlow>	
+</pre>
+To reverse the actions, just reverse the action specifiers. The WSS4J
+handler encrypts the SOAP Body first, then signs the encrypted data.
+
+<h3>Signing and encrypting multiple XML elements</h3>
+
+Sometimes it is necessary to sign and/or encrypt several parts of a SOAP
+message. The deployment parameters <code>signatureParts</code> and 
+<code>encryptionParts</code> control which SOAP elements to sign or
+to encrypt. Please refer to the
+{@link org.apache.ws.security.handler.WSHandlerConstants#ENCRYPTION_PARTS 
+detailed} description of these parameters.
+<p/>
+WSS4J signs or encrypts all declared parts using the same keys, that is 
+the signature or encryption data structures directly reference the 
+specified parts as described in the WSS specifications. The receiver
+automatically detects these references and verfies and decrypts the
+data parts. No special settings in the depolyment descriptor is necessary.
+
+<h3>Chaining of WSS4J Axis handlers</h3>
+
+This is a very powerful feature that supports even more flexible signature and
+encryption processing such as signatures with multiple keys (overlapping
+signatures), multiple encryption algorithms, or different SOAP actor (role)
+defintions of the security headers.
+
+<h4>Deployment at the client</h4>
+A deployment descriptor to chain handlers:
+<pre>
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    &lt;parameter name="action" value="Signature NoSerialization"/>
+    &lt;parameter name="user" value="firstUser"/>
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="signaturePropFile" value="crypto.properties" />
+    &lt;parameter name="signatureParts" value="{}{http://xmlsoap.org/Ping}ticket" />    
+   &lt;/handler>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
+    &lt;parameter name="action" value="Signature"/>
+    &lt;parameter name="user" value="anotherUser"/>
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="signaturePropFile" value="crypto.properties" />
+   &lt;/handler>  
+  &lt;/requestFlow>
+</pre>
+Note the action specifier <code>NoSerialization</code> first handler. 
+In a handler chain of WSS4J handlers every
+but the last handler <i>must</i> have this action specifier. This specifier
+surpresses the very last step of the handler's security processing: the 
+serialization of the processed SOAP request in a XML string (document) that 
+Axis sends to the reveiver. Only the last handler must perform this 
+serialization.
+<p/>
+Every handler specification can have its own set of parameters that define
+the individual values for this handler instance. Thus the deployment
+descriptor can define different crypto property files, different usernames,
+and so on. In the example the first handler signs the <code>ticket</code>
+element and the second handler the SOAP Body (default).
+<p/>
+Parameters set by the application with <code>setProperty</code> are valid for 
+<b>all</b> handler instances in the handler
+chain (<code>setProperty</code> is defined on the SOAP request (call) level).
+As already decribed, deployment settings overrule application settings. Thus it
+is possible to combine various parameter specifications. A special case is the
+definition of the username. If an application sets the username and one
+handler instance in the chain does not have a <code>user</code> parameter 
+in its deployment part, then this one handler instance uses the username set
+bey the application. After the handler copied the username from the username
+property, the handler sets the property's content to <code>null</code>. 
+Handlers that follow in the chain cannot use this username anymore and 
+must have a user (or encryption user) parameter in their deployment part.
+
+<h4>Deployment at the server</h4>
+
+Note: Handler chaining at the receiver side is not yet fully tested.
+<p/>
+Handlers at the receiver can only determine different security headers if their
+SOAP actors are different. The WSS4J handler processes each security structure
+inside one security header. Because the security structures contain most
+information to verify or decrypt the SOAP request this constraint is
+not too much of an issue.
+<p/>
+Only the password call back class and the <code>Crypto</code> implementation
+(as defined in the crypto property file) must be able to handle all possible 
+certificates, users, passwords, and keys that a security header may contain.
+The following deployment descriptor of a receiver shows this.
+<pre>
+  &lt;requestFlow>
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/>
+    &lt;parameter name="action" value="Signature Signature"/>
+    &lt;parameter name="signaturePropFile" value="crypto.properties" />
+   &lt;/handler>
+  &lt;/requestFlow>
+</pre>
+The client uses two handlers in a chain, each signing a part of the SOAP 
+request but with different certificates. Because the handlers do not 
+specifiy a SOAP actor WSS4J puts both signatures in the security header
+of the default actor. 
+To match the security actions the deployment descriptor of the receiver needs 
+to contain the action declaration <code>Signature Signature</code>. This 
+instructs the WSS4J handler to accept and verify two distinct signatures 
+contained in one security header. Because the signatures use different 
+certificates the <code>Crypto</code> implementation must be able to handle
+these certificates.
+<p/>
+Similar requirements are true for the password callback implementation if the
+sender uses handler chaining and uses different encryption parameters in the
+same security header.
+<p/>
+If it is necessary to have different parameters for the distinct signature or
+decryption data then these should be put in different security headers. The 
+easiest way to do this is to define different <code>actor</code> parameters
+for each handler in a WSS4J handler chain.
+ 
+<h3>Reporting Security results to services/applications</h3>
+The WSS4J <code>WSSecurityEngine</code> processes the security elements inside
+a security header. If something goes wrong, for example a signature 
+verfication fails, then the engine throws a fault. If the security engine
+could perform all operations sucessfully it returns a data structure
+that contains the results of the performed security actions. This data
+structure holds information about the performed action, the usernames or
+identifier in case the security engine performed signature or username token
+processing. Please refer to the
+{@link org.apache.ws.security.WSSecurityEngineResult result} structure.
+<p/>
+The <code>WSDoAllReceiver</code> WSS4J handler takes this structure and
+checks if all required actions were performed. If this check fails, the
+WSS4J handler aborts the SOAP request and throws an Axis SOAP fault.
+Otherwise it creates its own data structure 
+{@link org.apache.ws.security.handler.WSHandlerResult}, copies the
+security results in this structure, and adds the actor name of the
+security header. Then it stores this new data structure in a vector and stores
+this vector in a specific 
+{@link org.apache.ws.security.handler.WSHandlerConstants#RECV_RESULTS property} 
+of the current message context. If WSS4J handlers are
+chained, then every handler in the chain adds its result to the vector. The
+vector contains the results in handler-chain order.
+<p/>
+This code snippet shows how a Axis service can access the security result
+data:
+<pre>
+    public void ping(javax.xml.rpc.holders.StringHolder text,
+        org.apache.ws.axis.oasis.ping.TicketType ticket)
+        throws java.rmi.RemoteException {
+
+        text.value = "Echo " + text.value.trim();
+		
+        // get the message context first
+        MessageContext msgContext = MessageContext.getCurrentContext();
+        Message reqMsg = msgContext.getRequestMessage();
+
+        Vector results = null;
+        // get the result Vector from the property
+        if ((results =
+            (Vector) msgContext.getProperty(WSHandlerConstants.RECV_RESULTS))
+             == null) {
+            System.out.println("No security results!!");
+        }
+        System.out.println("Number of results: " + results.size());
+        for (int i = 0; i &lt; results.size(); i++) {
+            WSHandlerResult hResult = (WSHandlerResult)results.get(i);
+            String actor = hResult.getActor();
+            Vector hResults = hResult.getResults();
+            for (int j = 0; j < hResults.size(); j++) {
+              	WSSecurityEngineResult eResult = (WSSecurityEngineResult) hResults.get(j);
+                // Note: an encryption action does not have an associated principal
+    	        // only Signature and UsernameToken actions return a principal
+                if (eResult.getAction() != WSConstants.ENCR) {
+                    System.out.println(eResult.getPrincipal().getName());
+                }
+            }
+        }
+    }
+</pre>
+The principal structure is either a 
+{@link org.apache.ws.security.WSUsernameTokenPrincipal UsernameToken} principal 
+or a {@link java.security.Principal X509Principal}. The 
+princpals contain the names plus other information of the verified username
+token or signature certificate.
+ 
+<h3>Some hints</h3>
+
+<h4>Client</h4>
+At the client side, the WSS4J Axis handler, as all other parts of Axis, run
+in the context of the calling application. Depending on the application,
+the callback classes may perform complex operations, even do some user 
+interaction, to get the password or to access some database to get 
+certificates or keys. There are no timeouts defined at the client side 
+before the SOAP request is put on the wire.
+
+<h4>Server</h4>
+On the server side the WSS4J handler run in the same context as the other part
+of the server, usually some servlet container, such as Tomcat. Also the server
+must be able to handle many requests in a short time. Thus the password 
+callback as well as the <code>Crypto</code> implementation shall be
+as fast as possible. In general, no user interaction is possible at the
+server side to gather passwords. Also at this point of the SOAP request
+processing there are active timeouts, even if they are fairly long.
+
+<h4>Bi-directional SOAP Security</h4>
+WSS4J fully supports bi-directional SOAP security. To enable bi-directional
+support just put <code>WSDoAllSender</code> on the 
+<code>responseFlow</code> at the server and <code>WSDoAllReceiver</code>
+at the response flow of the client thus reversing the roles. Similar to
+the above hints, the server side part (now <code>WSDoAllSender</code>)
+runs in the server context and <code>WSDoAllReceiver</code>
+runs in the application (client) context. There are no Axis timeout
+constraints on the client side after Axis received the response 
+and handed it over to the WSS4J handler.
+
+<h4>Handler chaining</h4>
+Usually WSS4J handlers are chained without any other handler between them in
+the chain. It is, however, possible to do so. In this case the intermediate
+handler <b>must not</b> modify the SOAP Envelope that is contained in the
+Axis message. This could (most probably will) invalidate or destroy any 
+security actions done sofar. Such an intermediate handler may set some 
+properties that may influence the processing of the following WSS4J handler, 
+such as setting a new username, password callback class, and so on.
+
+<!-- Put @see and @since tags down here. -->
+@since WSS4J 1.0
+</body>
+</html>
diff --git a/src/org/apache/ws/sandbox/axis/security/conversation/ConvHandlerConstants.java b/src/org/apache/ws/sandbox/axis/security/conversation/ConvHandlerConstants.java
new file mode 100644
index 0000000..2863fdf
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/conversation/ConvHandlerConstants.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.axis.security.conversation;
+
+
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.ws.sandbox.security.conversation.ConversationConstants;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.xml.security.transforms.Transform;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+ * Represents parameters given in the wsdd file.
+ *
+ * @author Dimuthu Leelarathne.(muthulee@yahoo.com)
+ */
+public class ConvHandlerConstants {
+
+    private static Log log =
+        LogFactory.getLog(ConvHandlerConstants.class.getName());
+	
+    public static final String SEVER_PROP_FILE = "serverPropFile";
+    public static final String REQUESTOR_PROP_FILE = "requestorPropFile";
+    public static final String STS_PROP_FILE = "trustServicePropFile";
+
+    public static final String REAP_FREQ = "reapFrequency";
+    public static final String SESSION_DURATION = "sessionDuration";
+
+    public static final String KEY_FREQ = "keyFrequency";
+    public static final String USE_FIXED_KEYLEN = "useFixedKeyLegnth";
+
+    public static final String KEY_LEGNTH = "keyLegnth";
+    public static final String GENERATION = "generation";
+
+    public static final String SEVER_ALIAS = "serverAlias";
+    public static final String REQ_ALIAS = "requestorAlias";
+
+    public static final String SIGN_PARTS = "signatureParts";
+
+    public static final String TRUST_ENABLE = "trustEnable";
+
+    public static final String SCT_ESTABLISH_MTD = "sctEstablishmentMtd";
+    public static final String STS_REQUSTOR_TYPE = "stsRequestorType";
+
+    public static final String VERIFY_TRUST = "verifyTrust";
+
+    public static final String TRUST_ENGINE_PROP = "trustEngineProperties";
+
+    public static final String DK_ACTION = "derivedKeyAction";
+    public static final String APPLIES_TO_VAL = "appliesToValue";
+
+    public static Map sctEstablishmentMapper = new Hashtable();
+    
+    public static Map requesterTypeMapper = new Hashtable();
+    //TODO::Remove the below line
+	public static final String CONV_CALLBACK = "pwcallback";
+    
+    public static final String SCT_ISSUE_ACTION = "http://schemas.xmlsoap.org/ws/2005/XX/security/trust/RST/SCT";
+    
+    
+    
+	
+	/**
+	 * Which algorithm to be used for encryption as in AES or DES and so on
+	 * 
+	 * @see WSConstants#TRIPLE_DES
+     * @see WSConstants#AES_128
+     * @see WSConstants#AES_192
+     * @see WSConstants#AES_256
+	 */
+	public static final String DK_ENC_ALGO = "dkEncryptionAlgorithm";
+	
+	
+    
+    /*
+     * Constants needed for trust
+     */
+	public static final String STS_ADDRESS = "stsAddress";
+	public static final String SERVICE_EPR = "serviceEPR";
+    
+    
+    public static final String TOKEN_TRUST_VERIFY = "verifyToken";
+    
+    public static final String DK_CB_HANDLER = "DkcbHandler";
+    
+    /*
+     * Mapps the strings to internally used integers.
+     */
+    static {
+        sctEstablishmentMapper.put("DirectGenerated",
+                new Integer(ConversationConstants.DIRECT_GENERATED));
+        sctEstablishmentMapper.put("STSGenerated",
+                new Integer(ConversationConstants.STS_GENERATED));
+		sctEstablishmentMapper.put("STSRequestToken",
+						new Integer(ConversationConstants.STSREQUEST_TOKEN));
+		sctEstablishmentMapper.put("InteropHandshake",
+								new Integer(ConversationConstants.INTEROP_SCENE1));
+    }
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/conversation/ConversationClientHandler.java b/src/org/apache/ws/sandbox/axis/security/conversation/ConversationClientHandler.java
new file mode 100644
index 0000000..f57bfa5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/conversation/ConversationClientHandler.java
@@ -0,0 +1,856 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.axis.security.conversation;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.axis.handlers.BasicHandler;
+import org.apache.axis.message.MessageElement;
+import org.apache.axis.message.SOAPHeaderElement;
+import org.apache.commons.logging.Log;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.sandbox.security.conversation.ConversationConstants;
+import org.apache.ws.sandbox.security.conversation.ConversationEngine;
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+import org.apache.ws.sandbox.security.conversation.ConversationManager;
+import org.apache.ws.sandbox.security.conversation.ConversationUtil;
+import org.apache.ws.sandbox.security.conversation.DerivedKeyCallbackHandler;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.info.SecurityContextInfo;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.sandbox.security.trust.message.token.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedSecurityToken;
+import org.apache.ws.security.util.StringUtil;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.transforms.Transform;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ *
+ * This handler performs the client side actions, in order to execute WS-Secure
+ * Conversation. It employs three major components;
+ * <br /> 1) DerivedKeyCallbackHandler.java - Interfacing to the derived key generation component.
+ * <br /> 2) ConversationEngine.java - Process and validate conversation elements.
+ * <br /> 3) ConversationClient.java - Creates conversation elements.
+ * 
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ * @author Kaushalye Kapruge.  (kaushalye@yahoo.com)
+ *
+ */
+
+public class ConversationClientHandler extends BasicHandler {
+    private static Log log =
+        LogFactory.getLog(ConversationClientHandler.class.getName());
+
+    private int keyLen = -1;
+    private RequestSecurityTokenResponse stRes;
+
+    private static DerivedKeyCallbackHandler dkcbHandler =
+        new DerivedKeyCallbackHandler();
+
+    // private int frequency = 1;
+    private WSSecurityEngine secEng = null;
+    private static String uuid = null;
+
+    private Crypto serverCrypto = null;
+    private String serverAlias = null;
+    private Crypto reqCrypto = null;
+    private Crypto stsCrypto = null;
+
+    private int sctEstablishment = -1;
+
+    private static boolean handShakeDone = false;
+    private boolean isSCTavailabe = false;
+    private static boolean isConfigured = false;
+    private boolean readCrypto = false;
+
+	private String appliesTo = null;
+	
+	private boolean isSessionInfoConfigured = false;
+	/* 
+	 * TODO :: For now we are allowing only fixed sized derived keys
+	 */
+	private boolean usedFixedKeys = true;
+	 
+    private HashMap configurator;
+
+    int[] actionsInt;
+
+    public ConversationClientHandler() throws AxisFault {
+        log.debug("ConversationClientHandler :: created");
+    }
+    
+    public ConversationClientHandler(DerivedKeyCallbackHandler dk) throws AxisFault {
+		dkcbHandler = dk;
+		log.debug("ConversationClientHandler :: created");
+    }
+
+    /**
+     * Method inherited from the BasicHandler.
+     * If in the request flow calls the doRequestMetod()
+     * else calls the doResponse() method. 
+     * 
+     */
+    public void invoke(MessageContext msg) throws AxisFault {
+        log.debug("ConversationClientHandler :: invoked");
+        System.out.println("ConversationClientHandler :: invoked");
+       if (msg.getPastPivot())
+            doResponse(msg);
+        else
+            doRequest(msg);
+    }
+
+    /**
+     * The method is called in the request flow.
+     * 
+     * Do request method behaves in two different was according to the fact that
+     * <p>initial handshake is done.</p>
+     * <p>OR</p>
+     * <p>initial handshake is not done, i.e. SCT is not in memory</p>
+     *
+     * <br/>If SCT is in memory(handshake is done), then conversation carried out 
+     * using it
+     * <br/>If Token is not in memory (handshake is not done), the the SCT generation
+     * method will be read from the wsdd file. According to the parameters read the 
+     * method will execute actions. 
+     * @param msg
+     * @throws AxisFault
+     */
+
+    private void doRequest(MessageContext msg) throws AxisFault {
+		if(!isSessionInfoConfigured){
+			initSessionInfo();
+			isSessionInfoConfigured = true;
+		}
+        
+        Message sm = msg.getCurrentMessage();
+        //SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
+        Document doc = null;
+
+        if (!handShakeDone) {
+
+            decodeSCTEstabParameter();
+			this.loadCrypto();
+           
+            switch (this.sctEstablishment) {
+
+                case ConversationConstants.DIRECT_GENERATED :
+                    this.doHandshake_Direct_Generated(sm);
+                    break;
+
+                case ConversationConstants.STS_GENERATED :
+                    this.doHandshake_STS_Generated(sm);
+                    break;
+
+                case ConversationConstants.STSREQUEST_TOKEN ://the scenario where STS signs the token.
+                    break;
+                
+//                case ConversationConstants.INTEROP_SCENE1 :
+//				    this.doHandlshake_Interop(sm);
+//                	break;
+                
+                default :
+                    throw new AxisFault("Unsupored STS establishment method.");
+
+            }
+
+            handShakeDone = true;
+
+        } else { // handshake is done.
+
+            log.debug("Token in memory .");
+            SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
+            try {
+                doc =
+                    ((org.apache.axis.message.SOAPEnvelope) sPart
+                        .getEnvelope())
+                        .getAsDocument();
+            } catch (Exception e) {
+                throw new AxisFault("CoversationClientHandler :: Cannot get the document");
+            }
+
+            try {
+
+                //				add the relavent SCT
+                Element securityHeader =
+                    WSSecurityUtil.findWsseSecurityHeaderBlock(
+                        doc,
+                        doc.getDocumentElement(),
+                        true);
+                WSSecurityUtil.appendChildElement(
+                    doc,
+                    securityHeader,
+                    (new SecurityContextToken(doc, uuid)).getElement());
+                ConversationManager manager = new ConversationManager();
+                for (int i = 0; i < this.actionsInt.length; i++) {
+                    // Derrive the token
+                    DerivedKeyInfo dkInfo =
+                        manager.createDerivedKeyToken(doc, uuid, dkcbHandler,null, keyLen);
+
+                    String genID = dkInfo.getId();
+                    SecurityTokenReference stRef =
+                        dkInfo.getSecTokRef2DkToken();
+                    if (actionsInt[i] == ConversationConstants.DK_ENCRYPT) {
+                        manager.performDK_ENCR(
+                            ConversationUtil.generateIdentifier(uuid, genID),
+                            "",
+                            true,
+                            doc,
+                            stRef,
+                            dkcbHandler, null,(String)this.configurator.get(ConvHandlerConstants.DK_ENC_ALGO));
+                    } else if(actionsInt[i]==ConversationConstants.DK_SIGN){
+                    	//TODO:
+                        manager.performDK_Sign(doc, dkcbHandler, uuid, dkInfo, null);
+                    }
+                    
+                    manager.addDkToken(doc,dkInfo);
+
+                }
+            } catch (ConversationException e1) {
+                e1.printStackTrace();
+                throw new AxisFault(
+                    "ConversationClientHandler ::" + e1.getMessage());
+            }
+
+            //set it as current message
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(doc, os, true);
+            String osStr = os.toString();
+            sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+
+        }
+
+    }
+    /**
+    * This method is called in the response. 
+    * If Security Context Token (SCT) is not in the message, then it throws a fault.
+    *
+    * @param msgContext
+    * @throws AxisFault
+    */
+    private void doResponse(MessageContext msgContext)
+        throws AxisFault { //for incoming message
+        Document doc = null;
+		if(!isSessionInfoConfigured){
+			initSessionInfo();
+			isSessionInfoConfigured = true;
+		}
+        Message message = msgContext.getCurrentMessage();
+        SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();
+//        if (!this.readCrypto) {
+//            this.loadCrypto();
+//        }
+        
+        Object obj = null; 
+        if((obj=msgContext.getProperty(ConvHandlerConstants.DK_CB_HANDLER))!=null){
+        	this.dkcbHandler = (DerivedKeyCallbackHandler)obj;
+        } 
+        try {
+            doc =
+                ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
+                    .getAsDocument();
+
+        } catch (Exception e) {
+            throw new AxisFault(
+                "WSDoAllSender: cannot get SOAP envlope from message" + e);
+        }
+
+        /*Get the derved key tokens.
+         *Add them to the convSession.
+         */
+
+        log.debug("I am in ClientHandler Response");
+        
+        
+        try{
+        ConversationEngine convEng = new ConversationEngine(this.configurator);
+		Vector results = convEng.processSecConvHeader(doc, "", dkcbHandler, (String)this.configurator.get(WSHandlerConstants.PW_CALLBACK_CLASS));
+				} catch (ConversationException e1) {
+					e1.printStackTrace();
+					throw new AxisFault("CovnersationServerHandler :: "+e1.getMessage());
+				}
+				
+				
+
+//stolen from WSDoallReciever
+  ByteArrayOutputStream os = new ByteArrayOutputStream();
+		  XMLUtils.outputDOM(doc, os, true);
+		  sPart.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);
+
+		  ArrayList processedHeaders = new ArrayList();
+				  Iterator iterator = message.getSOAPEnvelope().getHeaders().iterator();
+				  while (iterator.hasNext()) {
+					  org.apache.axis.message.SOAPHeaderElement tempHeader = (org.apache.axis.message.SOAPHeaderElement) iterator.next();
+					  if (tempHeader.isProcessed()) {
+						  processedHeaders.add(tempHeader.getQName());
+					  }
+				  }        
+  /*
+		   * set the original processed-header flags
+		   */
+		  iterator = processedHeaders.iterator();
+		  while (iterator.hasNext()) {
+			  QName qname = (QName) iterator.next();
+			  Enumeration enumHeaders = message.getSOAPEnvelope().getHeadersByName(qname.getNamespaceURI(), qname.getLocalPart());
+			  while(enumHeaders.hasMoreElements()) {
+				  org.apache.axis.message.SOAPHeaderElement tempHeader = (org.apache.axis.message.SOAPHeaderElement)enumHeaders.nextElement();
+				  tempHeader.setProcessed(true);
+			  }
+		  }	  
+		
+			/*
+				   * After setting the new current message, probably modified because
+				   * of decryption, we need to locate the security header. That is,
+				   * we force Axis (with getSOAPEnvelope()) to parse the string, build 
+				   * the new header. Then we examine, look up the security header 
+				   * and set the header as processed.
+				   * 
+				   * Please note: find all header elements that contain the same
+				   * actor that was given to processSecurityHeader(). Then
+				   * check if there is a security header with this actor.
+				   */
+
+				  SOAPHeader sHeader = null;
+				  try {
+					  sHeader = message.getSOAPEnvelope().getHeader();
+				  } catch (Exception ex) {
+					  throw new AxisFault("WSDoAllReceiver: cannot get SOAP header after security processing", ex);
+				  }
+
+				  Iterator headers = sHeader.examineHeaderElements("");
+
+				  SOAPHeaderElement headerElement = null;
+				  while (headers.hasNext()) {
+					  SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
+					  if (hE.getLocalName().equals(WSConstants.WSSE_LN)
+							  && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
+						  headerElement = hE;
+						  break;
+					  }
+				  }
+				  ((org.apache.axis.message.SOAPHeaderElement) headerElement).setProcessed(true);
+
+		
+		System.out.println("I am in ClientHndelr Response");
+          
+        
+    } //do response done
+
+    /**
+     * The method is responsible for generating a SCT. This implements the scenario
+     * described in the specification as "Security context token created by 
+     * one of the communicating parties and propagated with a message"
+     * 
+     * @param sm
+     * @throws AxisFault
+     */
+    private void doHandshake_Direct_Generated(Message sm) throws AxisFault {
+        Document doc = null;
+        SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
+        try {
+
+            log.debug("ConversationClientHandler :: Trust Not required");
+            doc =
+                ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
+                    .getAsDocument();
+            this.initSessionInfo();
+            this.stRes = new RequestSecurityTokenResponse(doc, true);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e.getMessage());
+        }
+
+        /*
+         * SCT is now created.
+         * Steps::
+         * 1)
+         * 2)SCTInfo in dkcbHandler
+         */
+        uuid = stRes.getRequestedSecurityToken().getSct().getIdentifier();
+
+        stRes.build(doc);
+        isSCTavailabe = true;
+
+        //Now encrypting with the base token
+        RequestedProofToken reqProof = stRes.getRequestedProofToken();
+
+        try {
+            reqProof.doEncryptProof(doc, this.serverCrypto, this.serverAlias);
+
+            SecurityContextInfo info =
+                new SecurityContextInfo(
+                    stRes.getRequestedSecurityToken().getSct(),
+                    reqProof,
+                    ((Integer) (configurator
+                        .get(ConvHandlerConstants.KEY_FREQ)))
+                        .intValue());
+
+            dkcbHandler.addSecurtiyContext(uuid, info);
+            /*
+             * Add session specific information to the dkcbHandler
+             * 1) Key frequency.
+             */
+            if (usedFixedKeys == true) {
+				Long ln = new Long((String)Integer.toString(keyLen));
+                dkcbHandler.setDerivedKeyLength(uuid, ln.longValue() );
+            }
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(doc, os, true);
+            String osStr = os.toString();
+            sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+        } catch (WSSecurityException e2) {
+            e2.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e2.getMessage());
+        } catch (ConversationException e2) {
+            e2.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e2.getMessage());
+        }
+
+    }
+
+    /**
+     * This method is repsonsible for obtaining the SCT from the STS.
+     * 
+     * Firstly, a method call to the STS is done, usig WS-Trust components.  
+     * 
+     * The STS will return a <RequestedSecurityTokenResponse> that contains 
+     * <RequestedProofToken> and <RequestedSecurityToken>
+     * 
+     * The returned <RequestedProofToken> is decrypted, and again encrypted with the servers
+     * certificate to create a new  <RequestedProofToken>.
+     * 
+     * The recieved <RequestedSecurityToken> and the newly created <RequestedProofToken> is
+     * added to the message.
+     *    
+     *
+     * @param sm
+     * @throws AxisFault
+     */
+    private void doHandshake_STS_Generated(Message sm) throws AxisFault {
+        Document doc = null;
+        MessageElement[] meArrRes = null;
+        String tmpStr = null;
+		String stsEndPoint, callbackHandler;
+		
+		
+		if ((tmpStr = (String) getOption(ConvHandlerConstants.STS_ADDRESS))
+			!= null) {
+				stsEndPoint =tmpStr;	    
+		}else{
+			throw new AxisFault("STS address is not set.");
+		}        
+        
+        if ((tmpStr =(String) getOption(ConvHandlerConstants.APPLIES_TO_VAL))
+						!= null) {
+							log.debug("Applies to value is read ::" + tmpStr);
+				this.appliesTo = tmpStr;			
+			}
+		
+		if ((tmpStr = (String) getOption(ConvHandlerConstants.CONV_CALLBACK))
+					!= null) {
+						callbackHandler =tmpStr;	    
+		}else{
+					throw new AxisFault("PasswordCallbackHandler is not set.");
+		}
+			
+//        try {
+////            TrustCommunicator tc =
+////                new TrustCommunicator(stsEndPoint);
+////            
+////            tc.requestSecurityToken(
+////                new URI(TrustConstants.ISSUE_SECURITY_TOKEN_RST),
+////                TokenType.SCT,this.appliesTo);
+////            
+////            meArrRes = tc.getResponse();
+////            log.debug(
+////                "TrustCommTester end length of elements in the response is "
+////                    + meArrRes.length);
+//
+//        } catch (MalformedURIException e1) {
+//            e1.printStackTrace();
+//            throw new AxisFault(
+//                "ConversationClientHandler ::" + e1.getMessage());
+//        } catch (Exception e1) {
+//            e1.printStackTrace();
+//            throw new AxisFault(
+//                "ConversationClientHandler ::" + e1.getMessage());
+//        }
+
+        // We have successfully recieved the message element part.
+        SecurityContextToken sct = null;
+        RequestedProofToken proof = null;
+
+        log.debug("Trust communitcator successfully completed.");
+        try {
+            MessageElement tmpEle = null;
+            for (int i = 0; i < meArrRes.length; i++) {
+                tmpEle = meArrRes[i];
+                QName el =
+                    new QName(tmpEle.getNamespaceURI(), tmpEle.getLocalName());
+
+                Element domEle = tmpEle.getAsDOM();
+
+                if (el.equals(RequestedSecurityToken.TOKEN)) {
+                    log.debug("Recognized RequestedSecurityToken.");
+
+                    NodeList ndList =
+                        domEle.getElementsByTagNameNS(
+                            SecurityContextToken.TOKEN.getNamespaceURI(),
+                            SecurityContextToken.TOKEN.getLocalPart());
+                    if (ndList.getLength() < 0) {
+                        throw new AxisFault("Unspported yet ..");
+                    }
+                    sct = new SecurityContextToken((Element) ndList.item(0));
+
+                    SOAPHeader soapHeader = sm.getSOAPHeader();
+                    soapHeader.addChildElement(
+                        "Security",
+                        WSConstants.WSSE_PREFIX,
+                        WSConstants.WSSE_NS);
+
+                    Iterator it = soapHeader.getChildElements();
+                    while (it.hasNext()) {
+                        SOAPHeaderElement shSecElem;
+                        if ((shSecElem = (SOAPHeaderElement) it.next())
+                            .getLocalName()
+                            .equals("Security")) {
+                            MessageElement rstr =
+                                new MessageElement(
+                                    RequestSecurityTokenResponse
+                                        .TOKEN
+                                        .getLocalPart(),
+                                    RequestSecurityTokenResponse
+                                        .TOKEN
+                                        .getPrefix(),
+                                    RequestSecurityTokenResponse
+                                        .TOKEN
+                                        .getNamespaceURI());
+                            rstr.addChild(tmpEle);
+                            shSecElem.addChildElement(rstr);
+                        }
+                    }
+                } else if (el.equals(RequestedProofToken.TOKEN)) {
+                    SOAPPart sPart =
+                        (org.apache.axis.SOAPPart) sm.getSOAPPart();
+                    doc =
+                        ((org.apache.axis.message.SOAPEnvelope) sPart
+                            .getEnvelope())
+                            .getAsDocument();
+                    //do decrytion - proof is encrypted with certificate of STS 
+                    proof = new RequestedProofToken(domEle);
+             
+             
+                    proof.doDecryption(callbackHandler, serverCrypto);
+
+                    byte[] bkArr = proof.getSharedSecret();
+                    RequestedProofToken newProof = new RequestedProofToken(doc);
+                    newProof.setSharedSecret(bkArr);
+                    newProof.doEncryptProof(
+                        doc,
+                        serverCrypto,
+                        this.serverAlias);
+
+                    Element secHeader =
+                        WSSecurityUtil.findWsseSecurityHeaderBlock(
+                            doc,
+                            doc.getDocumentElement(),
+                            true);
+
+                    Element ele =
+                        (Element) WSSecurityUtil.findElement(
+                            secHeader,
+                            RequestSecurityTokenResponse.TOKEN.getLocalPart(),
+                            RequestSecurityTokenResponse
+                                .TOKEN
+                                .getNamespaceURI());
+
+                    ele.appendChild(newProof.getElement());
+
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    XMLUtils.outputDOM(doc, os, true);
+                    String osStr = os.toString();
+                    sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+
+                }
+
+            } //for loop
+
+            this.initSessionInfo();
+            Integer keyFreq =
+                (Integer) this.configurator.get(ConvHandlerConstants.KEY_FREQ);
+            SecurityContextInfo sctInfo =
+                new SecurityContextInfo(sct, proof, keyFreq.intValue());
+            this.uuid = sct.getIdentifier();
+            dkcbHandler.addSecurtiyContext(uuid, sctInfo);
+
+            Boolean isFixedKey =
+                (Boolean) configurator.get(
+                    ConvHandlerConstants.USE_FIXED_KEYLEN);
+
+            if (this.usedFixedKeys==true) {
+                Long keyLen =
+                    (Long) this.configurator.get(
+                        ConvHandlerConstants.KEY_LEGNTH);
+                dkcbHandler.setDerivedKeyLength(uuid, keyLen.longValue());
+            }
+
+            handShakeDone = true;
+
+        } catch (WSSecurityException e3) {
+            e3.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e3.getMessage());
+        } catch (SOAPException e) {
+            e.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e.getMessage());
+        } catch (Exception e3) {
+            e3.printStackTrace();
+            throw new AxisFault(
+                "ConversationClientHandler ::" + e3.getMessage());
+        }
+
+    } //end of doHandshake_STS_Generated
+
+
+//    private void doHandlshake_Interop(Message sm) throws AxisFault{
+//    	
+//    	InteropHandshaker interop = new InteropHandshaker();
+//		interop.handshake(getOptions()); 
+//		//System.out.println("Ok back");
+//		this.dkcbHandler = interop.getDkcb(); 
+//		
+//		this.uuid = interop.getUuid();
+//		
+//
+//		log.debug("Done handlshake .");
+//		SOAPPart sPart = (org.apache.axis.SOAPPart) sm.getSOAPPart();
+//		Document doc = null;
+//		
+//		try {
+//			doc =
+//				((org.apache.axis.message.SOAPEnvelope) sPart
+//					.getEnvelope())
+//					.getAsDocument();
+//		} catch (Exception e) {
+//			throw new AxisFault("CoversationClientHandler :: Cannot get the document");
+//		}
+//
+//		try {
+//
+//			//				add the relavent SCT
+//			Element securityHeader =
+//				WSSecurityUtil.findWsseSecurityHeaderBlock(WSSConfig.getDefaultWSConfig(),
+//					doc,
+//					doc.getDocumentElement(),
+//					true);
+//			WSSecurityUtil.appendChildElement(
+//				doc,
+//				securityHeader,
+//				(new SecurityContextToken(doc, uuid)).getElement());
+//			ConversationManager manager = new ConversationManager();
+//					
+//			for (int i = 0; i < this.actionsInt.length; i++) {
+//				// Derrive the token
+//				System.out.println("UUID is "+this.uuid);
+//				DerivedKeyInfo dkInfo =
+//					manager.createDerivedKeyToken(doc, this.uuid, dkcbHandler,null,keyLen);
+//
+//				String genID = dkInfo.getId();
+//				SecurityTokenReference stRef =
+//					dkInfo.getSecTokRef2DkToken();
+//				if (actionsInt[i] == ConversationConstants.DK_ENCRYPT) {
+//					manager.performDK_ENCR(
+//						ConversationUtil.generateIdentifier(uuid, genID),
+//						"",
+//						true,
+//						doc,
+//						stRef,
+//						dkcbHandler, null, (String)this.configurator.get(ConvHandlerConstants.DK_ENC_ALGO));
+//				} else if(actionsInt[i]==ConversationConstants.DK_SIGN){
+//					//TODO:
+//					manager.performDK_Sign(doc, dkcbHandler, uuid, dkInfo, null);
+//				}
+//
+//				manager.addDkToken(doc,dkInfo);
+//			}
+//		} catch (ConversationException e1) {
+//			e1.printStackTrace();
+//			throw new AxisFault(
+//				"ConversationClientHandler ::" + e1.getMessage());
+//		}
+//
+//		//set it as current message
+//		ByteArrayOutputStream os = new ByteArrayOutputStream();
+//		XMLUtils.outputDOM(doc, os, true);
+//		String osStr = os.toString();
+//		sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+//		
+//    }
+    /**
+     * Reads configeration parameters from the wsdd file.
+     * @throws AxisFault
+     */
+    private void initSessionInfo() throws AxisFault {
+        /**
+         * Default values for a session. These will be overriden by WSDD file parameters.
+         */
+        this.configurator = new HashMap();
+        String tmpStr;
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.KEY_FREQ))
+            != null) {
+            log.debug("Key Frequency is set ::" + tmpStr);
+            this.configurator.put(
+                ConvHandlerConstants.KEY_FREQ,
+                new Integer(tmpStr));
+        }
+
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.DK_ACTION))
+            != null) {
+            log.debug("Derived Key Action is read ::" + tmpStr);
+            String[] action = StringUtil.split(tmpStr, ' ');
+            actionsInt = new int[action.length];
+
+            for (int i = 0; i < action.length; i++) {
+                if ((action[i]).equalsIgnoreCase("Signature")) {
+                    actionsInt[i] = ConversationConstants.DK_SIGN;
+                } else if ((action[i]).equalsIgnoreCase("Encrypt")) {
+                    actionsInt[i] = ConversationConstants.DK_ENCRYPT;
+                }
+            }
+        }
+        
+		if ((tmpStr =
+						(String) getOption(ConvHandlerConstants.KEY_LEGNTH))
+						!= null) {
+						log.debug("Key Frequency is set ::" + tmpStr);
+					this.keyLen=Integer.parseInt(tmpStr);
+					this.configurator.put(ConvHandlerConstants.KEY_LEGNTH, new Long(tmpStr));
+				}
+		
+       
+		if ((tmpStr =
+					(String) getOption(WSHandlerConstants.PW_CALLBACK_CLASS))
+					!= null) {
+						this.configurator.put(WSHandlerConstants.PW_CALLBACK_CLASS, tmpStr);
+				}else{
+					//throw new AxisFault("Set the pass word call back class.....");
+				} 
+
+
+
+		if((tmpStr =(String) getOption(ConvHandlerConstants.DK_ENC_ALGO))!= null) {
+						this.configurator.put(ConvHandlerConstants.DK_ENC_ALGO, tmpStr);
+				}
+		
+    }
+
+    /**
+     * Decodes the SCT establishment parameter set in the .wsdd
+     * @throws AxisFault
+     */
+    private void decodeSCTEstabParameter() throws AxisFault {
+        String tmpStr =
+            (String) getOption(ConvHandlerConstants.SCT_ESTABLISH_MTD);
+        log.debug(
+            "ConversationClientHandler :: Decording SCT establishing parameter");
+        if (tmpStr.equals(null)) {
+            throw new AxisFault("SCT establishing method not specified.");
+        } else {
+            Integer i =
+                (Integer) ConvHandlerConstants.sctEstablishmentMapper.get(
+                    tmpStr);
+            this.sctEstablishment = i.intValue();
+        }
+    }
+    
+    private int decodeSTSRequesterTypeParamer () throws AxisFault{
+		String tmpStr =
+					(String) getOption(ConvHandlerConstants.STS_REQUSTOR_TYPE);
+		log.debug("ConversationClientHandler :: Decording STS requeter type parameter");
+		if (tmpStr.equals(null)) {
+			throw new AxisFault("STS requeter type not specified.");
+		} else {
+			Integer i =
+				(Integer) ConvHandlerConstants.requesterTypeMapper.get(
+					tmpStr);
+					return i.intValue();
+		}
+    }
+
+    /**
+     * Loads the crypto property files
+     * @throws AxisFault
+     */
+    private void loadCrypto() throws AxisFault {
+        String tmpStr = null;
+
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.SEVER_PROP_FILE))
+            == null) {
+            throw new AxisFault("Error! No server server properties file in wsdd");
+        }
+
+        log.debug("Server prop file is " + tmpStr);
+
+        this.serverCrypto = CryptoFactory.getInstance(tmpStr);
+
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.SEVER_ALIAS))
+            == null) {
+            throw new AxisFault("Error! No server server properties file in wsdd");
+        }
+        this.serverAlias = tmpStr;
+
+             
+                
+
+    }
+
+    private void decodeDkAction() {
+
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/conversation/ConversationServerHandler.java b/src/org/apache/ws/sandbox/axis/security/conversation/ConversationServerHandler.java
new file mode 100644
index 0000000..24ac62d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/conversation/ConversationServerHandler.java
@@ -0,0 +1,564 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.sandbox.axis.security.conversation;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.axis.handlers.BasicHandler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.sandbox.security.conversation.*;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.StringUtil;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.transforms.Transform;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+
+/**
+ * Serverside handler that implements WS-Secure Conversation for Axis.
+ *
+ *
+ * @author Dimuthu Leealarthne. (muthulee@yahoo.com)
+ *
+ */
+public class ConversationServerHandler extends BasicHandler {
+    private static Log log =
+            LogFactory.getLog(ConversationServerHandler.class.getName());
+    private boolean doDebug = false;
+
+    private static DerivedKeyCallbackHandler dkcbHandler =
+            new DerivedKeyCallbackHandler();
+
+    private static boolean isConfigured = false;
+    private SOAPConstants soapConstants = null;
+
+    private HashMap configurator = new HashMap();
+
+    private int[] actionsInt = null;
+
+    private boolean isSessionInfoConfigured = false;
+
+    private boolean isInitTrustVerified = false;
+
+    private Vector sigParts=null;
+    private Vector encParts=null;
+
+    private int keyLen =-1;
+
+    public ConversationServerHandler() {
+        log.debug("ConversationServerHandler :: created");
+    }
+
+    /**
+     * Method inherited from the BasicHandler.
+     * If in the request flow calls the doRequestMetod()
+     * else calls the doResponse() method.
+     *
+     */
+    public void invoke(MessageContext msg) throws AxisFault {
+        log.debug("ConversationServerHandler :: invoked");
+
+        if (msg.getPastPivot())
+            doResponse(msg);
+        else
+            doRequest(msg);
+    }
+
+    /**
+     * Called in the request flow of the request.
+     * Method looks for a SecurityToken in the SOAP envelope.
+     * Process the header.
+     *
+     *  @param msg
+     * @throws AxisFault
+     */
+    private void doRequest(MessageContext msg) throws AxisFault {
+        if(!isSessionInfoConfigured){
+            initSessionInfo();
+            isSessionInfoConfigured = true;
+        }
+
+
+        Document doc = null;
+        Message message = msg.getCurrentMessage();
+
+        // Get the soap message as a Docuemnt
+        SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();
+        try {
+            doc =
+                    ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
+                    .getAsDocument();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+//		if((this.configurator = (HashMap)msg.getProperty("PolicyObject"))==null){
+//			log.debug("ConversationServerHandler :: I am configuring");
+//		       initSessionInfo(); // load values to this.configurator from wsdd
+//		}
+
+        soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+        ConversationEngine eng = new ConversationEngine(this.configurator);
+
+//		try {
+//            boolean trustEngineResult = false;
+//            		if(!isInitTrustVerified){
+//            		String tmpStr = null;
+//            			if ((tmpStr = (String) getOption(ConvHandlerConstants.TOKEN_TRUST_VERIFY))
+//            						!= null) {
+//            			if(Boolean.getBoolean(tmpStr)){
+//            			  String trustPropFile = (String) getOption(ConvHandlerConstants.TRUST_ENGINE_PROP);
+//            			  TrustEngine trstEngine = new TrustEngine(trustPropFile);
+//            			  System.out.println("call the engine here ...");
+//            			  trustEngineResult=true;
+//            			}
+//            			isInitTrustVerified = true;
+//                        }
+//            		}
+//            if(trustEngineResult){
+//                 //getUUID and proof of possession
+//                 //add it to the derived key token
+//            }
+//        } catch (WSTrustException e2) {
+//            // TODO Auto-generated catch block
+//            e2.printStackTrace();
+//        }
+
+
+
+        try {
+            Vector results = eng.processSecConvHeader(doc, "", dkcbHandler, (String)this.configurator.get(WSHandlerConstants.PW_CALLBACK_CLASS));
+            ConvEngineResult convResult  = null;
+            String uuid = "";
+
+            /*put the actions into a stack to obtain LIFO behavior
+            * Rational for using the stack;
+            *
+            * Consider "Signature Encrypt"
+            * Then the ConvEngine Results will be in the order "Encrypt Signature"
+            * i.e. ConvEngine reusult containing ConvEngineResult.ENCRYPT_DERIVED_KEY
+            * will be before ConvEngineResult.SIGN_DERIVED_KEY
+            *
+            * Hense I need to read actions in the order of Last in First out - the stack
+            *
+            * This is same for "Encrypt Signature" visa versa.
+            */
+            Stack stk = new Stack();
+            for(int i=0; i<actionsInt.length ; i++){
+                stk.push(new Integer(actionsInt[i]));
+            }
+            int act = -1;
+            boolean rstr = false;
+            for(int i=0; i<results.size(); i++){
+                convResult=(ConvEngineResult)results.get(i);
+
+                switch(convResult.getAction()){
+
+                    case ConvEngineResult.SECURITY_TOKEN_RESPONSE :
+                        log.debug("ConversationServerHandler :: Found RSTR result");
+                        uuid = convResult.getUuid();
+                        rstr = true;
+                        break;
+
+                    case ConvEngineResult.ENCRYPT_DERIVED_KEY :
+                        log.debug("ConversationServerHandler :: Found dk_encrypt result");
+//				    if(stk.isEmpty()){
+//				    	throw new AxisFault("Action mismatch");
+//				    }
+//
+//				    act =((Integer)stk.pop()).intValue();
+//				    if(act == ConversationConstants.DK_ENCRYPT){
+//				    	//fine do nothing
+//				    }else{
+//				    	throw new AxisFault("Mismatch action order");
+//				    }
+                        break;
+
+                    case ConvEngineResult.SIGN_DERIVED_KEY :
+                        log.debug("ConversationServerHandler :: Found dk_sign result");
+//					if(stk.isEmpty()){
+//						throw new AxisFault("Action mismatch");
+//					}
+//					act =((Integer)stk.pop()).intValue();
+//					if(act == ConversationConstants.DK_SIGN){
+//					    //fine do nothing
+//					}else{
+//						throw new AxisFault("Mismatch action order");
+//					}
+                        break;
+
+                    case ConvEngineResult.SCT :
+                        log.debug("ConversationServerHandler :: Found SCT result");
+                        uuid = convResult.getUuid();
+                        break;
+
+                }
+            }
+
+            if(uuid.equals("")||(uuid==null)){
+                //throw new AxisFault("ConversationServerHandler :: Cannot find Session.");
+            }else{
+                msg.setProperty(ConversationConstants.IDENTIFIER,uuid);
+            }
+
+//
+//		    if(!rstr){
+//		    if(!stk.isEmpty()){
+//			  throw new AxisFault("Action mismatch. Required action missing");
+//			}
+//            }
+
+
+        } catch (ConversationException e1) {
+            e1.printStackTrace();
+            throw new AxisFault("CovnersationServerHandler :: "+e1.getMessage());
+        }
+
+
+
+        // Replace sPart with the new sPart.
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        XMLUtils.outputDOM(doc, os, true);
+        String osStr = os.toString();
+        sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+
+        //Following sets the headers as processed.
+        SOAPHeader sHeader = null;
+        try {
+            sHeader = message.getSOAPEnvelope().getHeader();
+        } catch (Exception ex) {
+            throw new AxisFault(
+                    "ConversatonServerHandler: cannot get SOAP header after security processing",
+                    ex);
+        }
+        String actor = null;
+        Iterator headers = sHeader.examineHeaderElements(actor);
+
+        SOAPHeaderElement headerElement = null;
+        while (headers.hasNext()) {
+            SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
+            if (hE.getLocalName().equals(WSConstants.WSSE_LN)
+                    && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
+                headerElement = hE;
+                break;
+            }
+        }
+        (
+                (
+                org
+                .apache
+                .axis
+                .message
+                .SOAPHeaderElement) headerElement)
+                .setProcessed(
+                        true);
+
+        msg.setProperty(ConvHandlerConstants.DK_CB_HANDLER,dkcbHandler);
+    } //do request
+
+    /**
+     * This method is called in the response.
+     * This method should
+     * 1) Add derived keys to the message as required.
+     * 2) Sign/encrypt as required.
+     *
+     * @param msg
+     * @throws AxisFault
+     */
+    private void doResponse(MessageContext msg) throws AxisFault {
+
+        if(!isSessionInfoConfigured){
+            initSessionInfo();
+            isSessionInfoConfigured = true;
+        }
+
+        //System.out.println("Doing response .... ");
+        Document doc = null;
+        Message message = msg.getCurrentMessage();
+        String uuid, identifier;
+        //	Code to get the soap message as a Docuemnt
+        SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();
+
+        try {
+            if ((doc = (Document) msg.getProperty(WSHandlerConstants.SND_SECURITY))
+                    == null) {
+                doc =
+                        ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
+                        .getAsDocument();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new AxisFault("CovnersationServerHandler :: "+e.getMessage());
+        }
+
+        //get the uuid
+        uuid = (String) msg.getProperty(ConversationConstants.IDENTIFIER);
+
+        if (uuid == null) {
+            //TODO :: throw exception
+            System.out.println("UUID NULl line :: 346");
+        }
+
+
+        try {
+            ConversationSession session = dkcbHandler.getSession(uuid);
+
+            if(session.isAddBase2Message()){
+                //add the relavent SCT
+                Element securityHeader =
+                        WSSecurityUtil.findWsseSecurityHeaderBlock(
+                                doc,
+                                doc.getDocumentElement(),
+                                true);
+                WSSecurityUtil.appendChildElement(
+                        doc,
+                        securityHeader,
+                        (new SecurityContextToken(doc, uuid)).getElement());
+            }
+
+            ConversationManager manager = new ConversationManager();
+
+            for (int i = 0; i < this.actionsInt.length; i++) {
+
+                // Derrive the token
+                SecurityTokenReference stRef2Base = null;
+                if(session.getRef2Base()==null){
+                    //do nothing
+                }else{
+                    stRef2Base = new SecurityTokenReference(doc);
+                    Reference ref = new Reference(doc);
+                    Reference oldRef = session.getRef2Base();
+
+                    ref.setURI(oldRef.getURI());
+                    ref.setValueType(oldRef.getValueType());
+                    stRef2Base.setReference(ref);
+                }
+                DerivedKeyInfo dkInfo =
+                        manager.createDerivedKeyToken(doc, uuid, dkcbHandler,stRef2Base, keyLen);
+
+                String genID = dkInfo.getId();
+                SecurityTokenReference stRef =
+                        dkInfo.getSecTokRef2DkToken();
+
+                if (actionsInt[i] == ConversationConstants.DK_ENCRYPT) {
+                    manager.performDK_ENCR(
+                            ConversationUtil.generateIdentifier(uuid, genID),
+                            "",
+                            true,
+                            doc,
+                            stRef,
+                            dkcbHandler, this.encParts, (String)this.configurator.get(ConvHandlerConstants.DK_ENC_ALGO));
+
+                } else if(actionsInt[i]==ConversationConstants.DK_SIGN){
+                    //TODO
+                    manager.performDK_Sign(doc, dkcbHandler, uuid, dkInfo,this.sigParts);
+                }
+
+                manager.addDkToken(doc,dkInfo);
+
+            }
+        } catch (ConversationException e1) {
+            e1.printStackTrace();
+            throw new AxisFault(
+                    "ConversationClientHandler ::" + e1.getMessage());
+        }
+
+        //set it as current message
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        XMLUtils.outputDOM(doc, os, true);
+        String osStr = os.toString();
+        sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);
+
+
+    } //doResponse
+
+    /**
+     * Conversation parameters are read from the wsdd file.
+     * When WS-Policy is implemented, these parameters should be
+     * configurable using policy components.
+     *
+     * @throws AxisFault
+     */
+    /**
+     * Reads configeration parameters from the wsdd file.
+     * @throws AxisFault
+     */
+    private void initSessionInfo() throws AxisFault {
+        /**
+         * Default values for a session. These will be overriden by WSDD file parameters.
+         */
+        this.configurator = new HashMap();
+        String tmpStr;
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.KEY_FREQ))
+                != null) {
+            log.debug("Key Frequency is set ::" + tmpStr);
+            this.configurator.put(
+                    ConvHandlerConstants.KEY_FREQ,
+                    new Integer(tmpStr));
+        }
+
+        if ((tmpStr = (String) getOption(ConvHandlerConstants.DK_ACTION))
+                != null) {
+            log.debug("Derived Key Action is read ::" + tmpStr);
+            String[] action = StringUtil.split(tmpStr, ' ');
+            actionsInt = new int[action.length];
+
+            for (int i = 0; i < action.length; i++) {
+                if ((action[i]).equalsIgnoreCase("Signature")) {
+                    actionsInt[i] = ConversationConstants.DK_SIGN;
+                } else if ((action[i]).equalsIgnoreCase("Encrypt")) {
+                    actionsInt[i] = ConversationConstants.DK_ENCRYPT;
+                }
+            }
+
+        }
+
+        if ((tmpStr =
+                (String) getOption(ConvHandlerConstants.SEVER_PROP_FILE))
+                != null) {
+            this.configurator.put(ConvHandlerConstants.SEVER_PROP_FILE, tmpStr);
+        }
+
+
+        if ((tmpStr =
+                (String) getOption(ConvHandlerConstants.KEY_LEGNTH))
+                != null) {
+            log.debug("Key Frequency is set ::" + tmpStr);
+            this.keyLen=Integer.parseInt(tmpStr);
+            this.configurator.put(ConvHandlerConstants.KEY_LEGNTH, new Long(tmpStr));
+        }
+
+
+        if ((tmpStr =
+                (String) getOption(WSHandlerConstants.PW_CALLBACK_CLASS))
+                != null) {
+            this.configurator.put(WSHandlerConstants.PW_CALLBACK_CLASS, tmpStr);
+        }else{
+            log.debug("Set the pass word call back class.");
+        }
+
+        if ((tmpStr =
+                (String) getOption(WSHandlerConstants.SIGNATURE_PARTS))
+                != null) {
+            this.sigParts = new Vector();
+            this.splitEncParts(tmpStr,sigParts);
+        }
+
+        if ((tmpStr =(String) getOption(WSHandlerConstants.ENCRYPTION_PARTS))
+                != null) {
+            this.encParts = new Vector();
+            this.splitEncParts(tmpStr,encParts);
+        }
+
+
+
+        if((tmpStr =(String) getOption(WSHandlerConstants.DEC_PROP_FILE))!= null) {
+            this.configurator.put(WSHandlerConstants.DEC_PROP_FILE, tmpStr);
+            System.out.println("Decryption properties read");
+        }
+
+        if((tmpStr =(String) getOption(ConvHandlerConstants.DK_ENC_ALGO))!= null) {
+            this.configurator.put(ConvHandlerConstants.DK_ENC_ALGO, tmpStr);
+        }
+
+
+
+
+
+    }
+
+
+    /**
+     * Extracted from the class <code>org.apache.ws.axis.security.WSDoAllSender.java</code>.
+     *
+     * @param tmpS
+     * @param encryptParts
+     * @throws AxisFault
+     */
+    private void splitEncParts(String tmpS, Vector encryptParts)
+            throws AxisFault {
+
+        WSEncryptionPart encPart = null;
+        String[] rawParts = StringUtil.split(tmpS, ';');
+
+        for (int i = 0; i < rawParts.length; i++) {
+            String[] partDef = StringUtil.split(rawParts[i], '}');
+
+            if (partDef.length == 1) {
+                if (doDebug) {
+                    log.debug("single partDef: '" + partDef[0] + "'");
+                }
+                encPart =
+                        new WSEncryptionPart(
+                                partDef[0].trim(),
+                                soapConstants.getEnvelopeURI(),
+                                "Content");
+            } else if (partDef.length == 3) {
+                String mode = partDef[0].trim();
+                if (mode.length() <= 1) {
+                    mode = "Content";
+                } else {
+                    mode = mode.substring(1);
+                }
+                String nmSpace = partDef[1].trim();
+                if (nmSpace.length() <= 1) {
+                    nmSpace = soapConstants.getEnvelopeURI();
+                } else {
+                    nmSpace = nmSpace.substring(1);
+                }
+                String element = partDef[2].trim();
+                if (doDebug) {
+                    log.debug(
+                            "partDefs: '"
+                            + mode
+                            + "' ,'"
+                            + nmSpace
+                            + "' ,'"
+                            + element
+                            + "'");
+                }
+                encPart = new WSEncryptionPart(element, nmSpace, mode);
+            } else {
+                throw new AxisFault(
+                        "WSDoAllSender: wrong part definition: " + tmpS);
+            }
+            encryptParts.add(encPart);
+        }
+    }
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/STSAgent.java b/src/org/apache/ws/sandbox/axis/security/trust/STSAgent.java
new file mode 100644
index 0000000..320f75d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/STSAgent.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.axis.security.trust;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Hashtable;
+
+import javax.xml.rpc.ServiceException;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.client.Call;
+import org.apache.axis.client.Service;
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.message.addressing.AddressingHeaders;
+import org.apache.axis.message.addressing.Constants;
+import org.apache.axis.message.addressing.handler.AddressingHandler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.axis.security.WSDoAllReceiver;
+import org.apache.ws.axis.security.WSDoAllSender;
+import org.apache.ws.sandbox.security.trust.message.token.RequestSecurityToken;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith (ruchith.fernando@gmail.com)
+ * 
+ * STSAgent is an axis specific component resides in the client side to request a token.
+ * The main task is to act as an Agent on behalf of the STS.
+ * 
+ * 
+ */
+public class STSAgent {
+    
+	static Log log = LogFactory.getLog(STSAgent.class.getName());
+    
+	private String url;
+    private RequestSecurityToken reqSecTok;
+    private Document doc;
+    private SOAPEnvelope env;
+    private Call call;
+    
+ /**
+  * Agent initialization
+  * @param url Endpoint Address
+  * @param senderOptions WSDoAllSender options
+  * @param recieverOptions WSDoAllReceiver options
+  * @param addConfig Addressing configuration for the STSAgent
+  * @throws ServiceException
+  * @throws MalformedURLException
+  * @throws Exception
+  * 
+  * @see org.apache.ws.axis.security.WSDoAllReceiver
+  * @see org.apache.ws.axis.security.WSDoAllSender
+  * @see STSAgentAddressingConfiguration
+  */
+    public STSAgent(String url,Hashtable senderOptions,Hashtable receiverOptions, STSAgentAddressingConfiguration addConfig)throws ServiceException,MalformedURLException,Exception{
+		Service service = new Service();
+		call = (Call) service.createCall();
+		//--
+		
+		WSDoAllSender doAllSender=new WSDoAllSender();
+		WSDoAllReceiver doAllReciever=new WSDoAllReceiver();
+		
+		// if there are options to encrypt and sign hand them over to WSDoAllSender/Reciever
+		if(senderOptions !=null){
+		    log.debug("WSDoAllSender options are null");
+			doAllSender.setOptions(senderOptions);			 
+		}
+		if(receiverOptions !=null){
+		    log.debug("WSDoAllReceiver options are null");
+			doAllReciever.setOptions(receiverOptions);		
+		}
+		call.setClientHandlers(doAllSender,doAllReciever);
+	
+		if(addConfig != null) { //If the addressing configuration is provided
+			System.out.println("Tired tired tired");
+			AddressingHandler addressingHandler = new AddressingHandler();
+			addressingHandler.setOption("removeHeaders","false");
+			AddressingHeaders headers = addConfig.getHeaders();
+			call.setProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS, headers);
+			call.setClientHandlers(addressingHandler,addressingHandler);
+		}
+
+		/*
+		 SET SECURITY HANDLERS
+			These should be added last at the client side since the 
+			WSDoAllSender should be executed last in the request flow and the
+			WSDoAllreceiver should be executed first in the response flow
+		*/
+		
+		//call.setClientHandlers(doAllSender,null);
+		
+		//--
+		this.url=url;
+		call.setTargetEndpointAddress(new URL(url));
+		log.debug("Endpoint Address : "+url);
+		env = new SOAPEnvelope();
+		doc = env.getAsDocument();
+		//reqSecTok=new RequestSecurityToken(doc);
+    }
+    
+
+    /**
+     * Agent initialization without addressing support
+     * I don't think this will be used at all :-?
+     * @param url
+     * @param senderOptions
+     * @param receiverOptions
+     * @throws ServiceException
+     * @throws MalformedURLException
+     * @throws Exception
+     */
+    public STSAgent(String url,Hashtable senderOptions,Hashtable receiverOptions)throws ServiceException,MalformedURLException,Exception{
+    	this(url,senderOptions,receiverOptions,null);
+    }
+    
+    /**
+     * Use this method to add any element to the request
+     * @param element
+     */
+    public void setAnyElement(Element element){
+        this.reqSecTok.addToken(element);
+    }
+    
+
+    /**
+     * request call
+     * Thank goes to David Del Vecchio for giving his code(=>idea)
+     * 
+     * @return 
+     * @throws AxisFault
+     * @throws Exception
+     */
+    public Element request()throws AxisFault,Exception{
+		SOAPBodyElement sbe = new SOAPBodyElement(reqSecTok.getElement());
+		this.env.addBodyElement(sbe);
+		log.debug("Invoke");
+		SOAPEnvelope response = call.invoke(env);
+		Element responseElement =response.getAsDOM();
+		return responseElement;
+    }
+    
+
+    public Document getDoc() {
+        return this.doc;
+    }
+    public SOAPEnvelope getEnv() {
+        return this.env;
+    }
+    
+	public void setEnv(SOAPEnvelope e) throws Exception {
+		this.env=e;
+		this.doc=env.getAsDocument();
+    }
+    
+    public RequestSecurityToken getReqSecTok() {
+        return this.reqSecTok;
+    }
+    public void setReqSecTok(RequestSecurityToken reqSecTok) {
+        this.reqSecTok = reqSecTok;
+    }
+    /**
+     * to retrieve the endpoint url of the agent
+     * @return 
+     */
+    public String getUrl() {
+        return this.url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/STSAgentAddressingConfiguration.java b/src/org/apache/ws/sandbox/axis/security/trust/STSAgentAddressingConfiguration.java
new file mode 100644
index 0000000..ef4c4cf
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/STSAgentAddressingConfiguration.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.axis.security.trust;
+
+
+import org.apache.axis.message.addressing.Action;
+import org.apache.axis.message.addressing.Address;
+import org.apache.axis.message.addressing.AddressingHeaders;
+import org.apache.axis.message.addressing.EndpointReference;
+import org.apache.axis.types.URI;
+import org.apache.axis.types.URI.MalformedURIException;
+
+/**
+ * This is used to provide the addressing headers required by the STSAgent 
+ * @author Ruchith
+ */
+public class STSAgentAddressingConfiguration {
+
+	private AddressingHeaders headers = new AddressingHeaders();
+	
+	/**
+	 * Set the action URI
+	 * @param actionUri 
+	 * @throws MalformedURIException
+	 */
+	public void setAction(String actionUri) throws MalformedURIException {
+		Action a = new Action(new URI(actionUri));
+		this.headers.setAction(a);
+	}
+	/**
+	 * SEt the from EPR
+	 * @param endpoint
+	 * @throws MalformedURIException
+	 */
+	public void setFrom(String endpoint) throws MalformedURIException {
+		this.headers.setFrom(new EndpointReference(endpoint));
+	}
+	
+	/**
+	 * Set the from EPR
+	 * @param endpoint
+	 * @throws MalformedURIException
+	 */
+	public void setFaultTo(String endpoint) throws MalformedURIException {
+		this.headers.setFaultTo(new EndpointReference(endpoint));
+	}
+	
+	/**
+	 * Return the configured addressing headers
+	 * @return
+	 */
+	public AddressingHeaders getHeaders() {
+		return this.headers;
+	}
+	
+	public void setRepyTo(String endpoint) throws MalformedURIException {
+		//this.headers.setReplyTo(new Address(endpoint));
+	}
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/STSServerHandler.java b/src/org/apache/ws/sandbox/axis/security/trust/STSServerHandler.java
new file mode 100644
index 0000000..dfbb1fc
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/STSServerHandler.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.axis.security.trust;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.axis.handlers.BasicHandler;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.security.trust.STSManager;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+
+import javax.xml.soap.SOAPHeader;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         <p/>
+ *         <code>STSServerHandler</code> is a handler which resides in the response path
+ *         of the Security Token Service end.
+ *         <code>STSServerHandler</code> currently performs following tasks
+ *         <ul>
+ *         <li>
+ *         Get the request from the message context
+ *         </li>
+ *         <li>
+ *         Create an <code>STSManager</code> and handover the task to be carried out.
+ *         </li>
+ *         <li>
+ *         Get the resulted SOAP enevelop from <code>STSManager</code>
+ *         </li>
+ *         <li>
+ *         Set the current message of the message context
+ *         </li>
+ *         <p/>
+ *         </ul>
+ */
+public class STSServerHandler extends BasicHandler {
+
+    static Log log = LogFactory.getLog(STSServerHandler.class.getName());
+
+    public STSServerHandler() {
+
+    }
+
+    /**
+     * Invoke method of handler
+     */
+    public void invoke(MessageContext msgCntxt) throws AxisFault {
+        log.debug("STSServerHandler: invoked");
+
+        if (msgCntxt.getPastPivot()) {
+            doRequest(msgCntxt);
+        } else {
+
+        }
+
+    }
+
+    /**
+     * Processing the outgoing msg
+     *
+     * @param msgCntxt
+     * @throws AxisFault
+     */
+    private void doRequest(MessageContext msgCntxt) throws AxisFault {
+        log.debug("STSServerHandler: doRequest");
+        SOAPHeader sHeader = null;
+        //get the request msg    
+        Message smReq = msgCntxt.getRequestMessage();
+        //get the response msg
+        Message smCurr = msgCntxt.getCurrentMessage();
+        //get the request msg as a SOAP part
+        SOAPPart sPartReq = (org.apache.axis.SOAPPart) smReq.getSOAPPart();
+        //get the response msg as a SOAP part
+        SOAPPart sPartRes = (org.apache.axis.SOAPPart) smCurr.getSOAPPart();
+
+        Document docReq, docRes = null;
+
+        try {
+            //initialize xml security
+            org.apache.xml.security.Init.init();
+            docReq = ((SOAPEnvelope) sPartReq.getEnvelope()).getAsDocument();
+            docRes = ((SOAPEnvelope) sPartRes.getEnvelope()).getAsDocument();
+
+            ByteArrayOutputStream osReq = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(docReq, osReq, true);
+
+            ByteArrayOutputStream osRes = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(docRes, osRes, true);
+            
+            //creates an STSManager and handover server-config.wsdd parameters in a hash table
+            log.debug("STSServerHandler: calling STSManager");
+            STSManager stsMgr =
+                    new STSManager(this.getOptions());
+            docRes = stsMgr.handleRequest(docReq, docRes);
+            log.debug("STSServerHandler: STSManager has done the job");
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(docRes, os, true); 
+            //modify the current message
+            sPartRes.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);            
+            //set current message to the context
+            msgCntxt.setCurrentMessage(sPartRes.getMessage());
+
+        } catch (Exception ex) {
+            throw new AxisFault("STSServerHandler-dorequest:Response failed due to a problem in issuence process",
+                    ex);
+        }
+
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/service/RequestSecurityTokenType.java b/src/org/apache/ws/sandbox/axis/security/trust/service/RequestSecurityTokenType.java
new file mode 100644
index 0000000..c6d240c
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/service/RequestSecurityTokenType.java
@@ -0,0 +1,161 @@
+/**
+ * RequestSecurityTokenType.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis #axisVersion# #today# WSDL2Java emitter.
+ */
+
+package org.apache.ws.sandbox.axis.security.trust.service;
+
+
+/**
+ * Actual content model is non-deterministic, hence wildcard. The
+ * following shows intended content model:
+ */
+public class RequestSecurityTokenType  implements java.io.Serializable, org.apache.axis.encoding.AnyContentType {
+    private org.apache.axis.message.MessageElement [] _any;
+    private org.apache.axis.types.URI context;  // attribute
+
+    public RequestSecurityTokenType() {
+    }
+
+    public RequestSecurityTokenType(
+           org.apache.axis.message.MessageElement [] _any,
+           org.apache.axis.types.URI context) {
+           this._any = _any;
+           this.context = context;
+    }
+
+
+    /**
+     * Gets the _any value for this RequestSecurityTokenType.
+     * 
+     * @return _any
+     */
+    public org.apache.axis.message.MessageElement [] get_any() {
+        return _any;
+    }
+
+
+    /**
+     * Sets the _any value for this RequestSecurityTokenType.
+     * 
+     * @param _any
+     */
+    public void set_any(org.apache.axis.message.MessageElement [] _any) {
+        this._any = _any;
+    }
+
+
+    /**
+     * Gets the context value for this RequestSecurityTokenType.
+     * 
+     * @return context
+     */
+    public org.apache.axis.types.URI getContext() {
+        return context;
+    }
+
+
+    /**
+     * Sets the context value for this RequestSecurityTokenType.
+     * 
+     * @param context
+     */
+    public void setContext(org.apache.axis.types.URI context) {
+        this.context = context;
+    }
+
+    private java.lang.Object __equalsCalc = null;
+    public synchronized boolean equals(java.lang.Object obj) {
+        if (!(obj instanceof RequestSecurityTokenType)) return false;
+        RequestSecurityTokenType other = (RequestSecurityTokenType) obj;
+        if (obj == null) return false;
+        if (this == obj) return true;
+        if (__equalsCalc != null) {
+            return (__equalsCalc == obj);
+        }
+        __equalsCalc = obj;
+        boolean _equals;
+        _equals = true && 
+            ((this._any==null && other.get_any()==null) || 
+             (this._any!=null &&
+              java.util.Arrays.equals(this._any, other.get_any()))) &&
+            ((this.context==null && other.getContext()==null) || 
+             (this.context!=null &&
+              this.context.equals(other.getContext())));
+        __equalsCalc = null;
+        return _equals;
+    }
+
+    private boolean __hashCodeCalc = false;
+    public synchronized int hashCode() {
+        if (__hashCodeCalc) {
+            return 0;
+        }
+        __hashCodeCalc = true;
+        int _hashCode = 1;
+        if (get_any() != null) {
+            for (int i=0;
+                 i<java.lang.reflect.Array.getLength(get_any());
+                 i++) {
+                java.lang.Object obj = java.lang.reflect.Array.get(get_any(), i);
+                if (obj != null &&
+                    !obj.getClass().isArray()) {
+                    _hashCode += obj.hashCode();
+                }
+            }
+        }
+        if (getContext() != null) {
+            _hashCode += getContext().hashCode();
+        }
+        __hashCodeCalc = false;
+        return _hashCode;
+    }
+
+    // Type metadata
+    private static org.apache.axis.description.TypeDesc typeDesc =
+        new org.apache.axis.description.TypeDesc(RequestSecurityTokenType.class, true);
+
+    static {
+        typeDesc.setXmlType(new javax.xml.namespace.QName("http://schemas.xmlsoap.org/ws/2005/02/trust", "RequestSecurityTokenType"));
+        org.apache.axis.description.AttributeDesc attrField = new org.apache.axis.description.AttributeDesc();
+        attrField.setFieldName("context");
+        attrField.setXmlName(new javax.xml.namespace.QName("", "Context"));
+        attrField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "anyURI"));
+        typeDesc.addFieldDesc(attrField);
+    }
+
+    /**
+     * Return type metadata object
+     */
+    public static org.apache.axis.description.TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
+    /**
+     * Get Custom Serializer
+     */
+    public static org.apache.axis.encoding.Serializer getSerializer(
+           java.lang.String mechType, 
+           java.lang.Class _javaType,  
+           javax.xml.namespace.QName _xmlType) {
+           
+        return 
+          new  org.apache.axis.encoding.ser.BeanSerializer(
+            _javaType, _xmlType, typeDesc);
+    }
+
+    /**
+     * Get Custom Deserializer
+     */
+    public static org.apache.axis.encoding.Deserializer getDeserializer(
+           java.lang.String mechType, 
+           java.lang.Class _javaType,  
+           javax.xml.namespace.QName _xmlType) {
+        return 
+          new  org.apache.axis.encoding.ser.BeanDeserializer(
+            _javaType, _xmlType, typeDesc);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenRequestService.java b/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenRequestService.java
new file mode 100644
index 0000000..f5db851
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenRequestService.java
@@ -0,0 +1,34 @@
+/**
+ * SecurityTokenRequestService.java
+ *
+ * This file was auto-generated from WSDL
+ * by the Apache Axis #axisVersion# #today# WSDL2Java emitter.
+ */
+
+package org.apache.ws.sandbox.axis.security.trust.service;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+
+
+public class SecurityTokenRequestService {
+    public void requestSecurityToken(org.apache.ws.sandbox.axis.security.trust.service.RequestSecurityTokenType request) throws java.rmi.RemoteException{
+              MessageContext context = MessageContext.getCurrentContext();
+              
+//              try {
+//                context.setResponseMessage(getSOAPMessage());
+//            } catch (Exception e) {
+//                System.out.println(e.getMessage());
+//                e.printStackTrace();
+//            }
+    }
+    
+	protected Message getSOAPMessage() throws Exception {
+		   InputStream in = new FileInputStream("response.xml");
+		   Message msg = new Message(in);
+		   return msg;
+	   }
+}
diff --git a/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenService.java b/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenService.java
new file mode 100644
index 0000000..3adceca
--- /dev/null
+++ b/src/org/apache/ws/sandbox/axis/security/trust/service/SecurityTokenService.java
@@ -0,0 +1,108 @@
+/*
+ * Created on Aug 29, 2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+package org.apache.ws.sandbox.axis.security.trust.service;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.xml.soap.SOAPHeader;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.SOAPPart;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.utils.ByteArrayOutputStream;
+import org.apache.ws.sandbox.security.trust.STSManager;
+import org.apache.ws.security.util.Loader;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+
+/**
+ * @author Ruchith
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+public class SecurityTokenService {
+
+	protected Hashtable options;
+	
+	public SecurityTokenService() {
+		this.loadProperties("STS.properties");
+	}
+	
+	public void requestSecurityToken(org.apache.ws.sandbox.axis.security.trust.service.RequestSecurityTokenType request) throws java.rmi.RemoteException{
+    	try{
+    		MessageContext msgCntxt = MessageContext.getCurrentContext();
+	    	msgCntxt.getRequestMessage();
+	    	
+	        SOAPHeader sHeader = null;
+	        //get the request msg    
+	        Message smReq = msgCntxt.getRequestMessage();
+	        //get the response msg
+	       // Message smCurr = msgCntxt.getCurrentMessage();
+		   Message smCurr = msgCntxt.getResponseMessage();//.getRequestMessage();
+	        //get the request msg as a SOAP part
+	        SOAPPart sPartReq = (org.apache.axis.SOAPPart) smReq.getSOAPPart();
+	        //get the response msg as a SOAP part
+	        SOAPPart sPartRes = (org.apache.axis.SOAPPart) smCurr.getSOAPPart();
+
+	        Document docReq, docRes = null;
+
+	        try {
+	            //initialize xml security
+	            org.apache.xml.security.Init.init();
+	            docReq = ((SOAPEnvelope) sPartReq.getEnvelope()).getAsDocument();
+	            docRes = ((SOAPEnvelope) sPartRes.getEnvelope()).getAsDocument();
+
+	            STSManager stsMgr =
+	                    new STSManager(this.options);
+	            docRes = stsMgr.handleRequest(docReq, docRes);
+//	            log.debug("STSServerHandler: STSManager has done the job");
+	            ByteArrayOutputStream os = new ByteArrayOutputStream();
+	            XMLUtils.outputDOM(docRes, os, true); 
+	            //modify the current message
+	            sPartRes.setCurrentMessage(os.toByteArray(), SOAPPart.FORM_BYTES);   
+	            //set current message to the context
+				//msgCntxt.setCurrentMessage(sPartRes.getMessage());
+				//msgCntxt.setPastPivot(true);
+				//msgCntxt.setPastPivot(true);
+				msgCntxt.setCurrentMessage(sPartRes.getMessage());
+	          // msgCntxt.setResponseMessage(sPartRes.getMessage());
+			 
+
+	        } catch (Exception ex) {
+	            throw new AxisFault("STSServerHandler-dorequest:Response failed due to a problem in issuence process",
+	                    ex);
+	        }
+
+    	} catch (Exception e) {
+    		System.out.println("Exception is "+e.getMessage());
+    		throw new AxisFault();
+    	}
+    }
+
+    protected void loadProperties(String propFilename) {
+        Properties properties = new Properties();
+        try {
+            URL url = Loader.getResource(propFilename);
+            properties.load(url.openStream());
+        } catch (Exception e) {
+            throw new RuntimeException("SecurityTokenSErvice: Cannot load properties: " + propFilename);
+        }
+        this.options = new Hashtable();
+        Enumeration enumKeys = properties.keys();
+        while(enumKeys.hasMoreElements()) {
+        	String key = (String)enumKeys.nextElement();
+        	this.options.put(key,properties.getProperty(key));
+        }
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/package.html b/src/org/apache/ws/sandbox/package.html
new file mode 100644
index 0000000..d414ebb
--- /dev/null
+++ b/src/org/apache/ws/sandbox/package.html
@@ -0,0 +1,5 @@
+<html>
+<! -- $Id$ -->
+<body>
+This package contains parts of WSS4J that are experimental.
+</body>
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConvEngineResult.java b/src/org/apache/ws/sandbox/security/conversation/ConvEngineResult.java
new file mode 100644
index 0000000..c95017c
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConvEngineResult.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+/**
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ */
+public class ConvEngineResult {
+    public static final int SECURITY_TOKEN_RESPONSE = 1;
+    public static final int SIGN_DERIVED_KEY = 2;
+    public static final int ENCRYPT_DERIVED_KEY = 3;
+    public static final int TRUST_VERIFIED = 4;
+    public static final int SCT = 5;
+
+    private String uuid = null;
+    byte[] keyAssociated = null;
+    private int Action;
+
+    public ConvEngineResult(int Act) {
+        this.Action = Act;
+    }
+
+    /**
+     * @return
+     */
+    public int getAction() {
+        return Action;
+    }
+
+    /**
+     * @return
+     */
+    public String getUuid() {
+        return uuid;
+    }
+
+    /**
+     * @param i
+     */
+    public void setAction(int i) {
+        Action = i;
+    }
+
+    /**
+     * @param string
+     */
+    public void setUuid(String string) {
+        uuid = string;
+    }
+
+    /**
+     * @return
+     */
+    public byte[] getKeyAssociated() {
+        return keyAssociated;
+    }
+
+    /**
+     * @param bs
+     */
+    public void setKeyAssociated(byte[] bs) {
+        keyAssociated = bs;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationConstants.java b/src/org/apache/ws/sandbox/security/conversation/ConversationConstants.java
new file mode 100644
index 0000000..e460699
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationConstants.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+/**
+ * Class ConversationConstants
+ */
+public class ConversationConstants {
+
+	private static final String NS_YEAR_PREFIX = "http://schemas.xmlsoap.org/ws/2005/02/";
+	
+    /**
+     * WS-Secure Conversation namespace
+     */
+    public final static String WSC_NS = NS_YEAR_PREFIX + "sc";
+    
+    /**
+     * TOken type of DerivedKeyToken
+     */
+    public final static String TOKEN_TYPE_DERIVED_KEY_TOKEN = WSC_NS + "/dk";
+    
+    /**
+     * Token type of SecurityContextToken
+     */
+    public static final String TOKEN_TYPE_SECURITY_CONTEXT_TOKEN = WSC_NS  + "/sct";
+    
+    /**
+     * Field WSC_PREFIX
+     */
+    public final static String WSC_PREFIX = "wsc";
+
+    /**
+     * Field SECURITY_CONTEXT_TOKEN_LN
+     */
+    public static final String SECURITY_CONTEXT_TOKEN_LN =
+            "SecurityContextToken";
+
+    /**
+     * Field IDENTIFIER_LN
+     */
+    public static final String IDENTIFIER_LN = "Identifier";
+
+    /**
+     * Field EXPIRES_LN
+     */
+    public static final String EXPIRES_LN = "Expires";
+
+    /**
+     * Field KEYS_LN
+     */
+    public static final String KEYS_LN = "Keys";
+
+    /**
+     * Field SECURITY_TOKEN_REFERENCE_LN
+     */
+    public static final String SECURITY_TOKEN_REFERENCE_LN =
+            "SecurityTokenReference";
+
+    /**
+     * Field DERIVED_KEY_TOKEN_LN
+     */
+    public static final String DERIVED_KEY_TOKEN_LN = "DerivedKeyToken";
+
+    /**
+     * Field PROPERTIES_LN
+     */
+    public static final String PROPERTIES_LN = "Properties";
+
+    /**
+     * Field LENGTH_LN
+     */
+    public static final String LENGTH_LN = "Length";
+
+    /**
+     * Field GENERATION_LN
+     */
+    public static final String GENERATION_LN = "Generation";
+
+    /**
+     * Field OFFSET_LN
+     */
+    public static final String OFFSET_LN = "Offset";
+
+    /**
+     * Field LABEL_LN
+     */
+    public static final String LABEL_LN = "Label";
+
+    /**
+     * Field NONCE_LN
+     */
+    public static final String NONCE_LN = "Nonce";
+
+    public static final int DIRECT_GENERATED = 1;
+    public static final int STS_GENERATED = 2;
+    public static final int STSREQUEST_TOKEN = 3;
+    public static final int INTEROP_SCENE1 = 4;
+
+    public static final String IDENTIFIER = "SCT_Identifier";
+
+    public static final int DK_SIGN = 1;
+    public static final int DK_ENCRYPT = 2;
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationEngine.java b/src/org/apache/ws/sandbox/security/conversation/ConversationEngine.java
new file mode 100644
index 0000000..852593f
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationEngine.java
@@ -0,0 +1,1021 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.axis.security.conversation.ConvHandlerConstants;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.info.SecurityContextInfo;
+import org.apache.ws.sandbox.security.conversation.message.token.DerivedKeyToken;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.EnvelopeIdResolver;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.TrustEngine;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.sandbox.security.trust.message.token.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.Loader;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Conversation Engine follows the basic structure of SecurityEngine<link>
+ *
+ * @author Dimuthu (muthulee@yahoo.com)
+ */
+public class ConversationEngine {
+    private static Log log =
+        LogFactory.getLog(ConversationEngine.class.getName());
+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");
+
+    private boolean doDebug = false;
+
+    /**
+     * <code>wsc:DerivedKeyToken</code> as defined in WS Secure Conversation specification.
+     */
+    protected static final QName DERIVEDKEY_TOKEN =
+        new QName(
+            ConversationConstants.WSC_NS,
+            ConversationConstants.DERIVED_KEY_TOKEN_LN);
+
+    /**
+     * <code>wsc:SecurityContextToken</code> as defined in WS Secure Conversation specification.
+     */
+    protected static final QName SCT_TOKEN =
+        new QName(
+            ConversationConstants.WSC_NS,
+            ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+    /**
+     * Refer WS secure Conversation specification
+     */
+    protected static final QName REQUESTED_SECURITY_TOKEN_RESPONSE =
+        new QName(
+            TrustConstants.WST_NS,
+            TrustConstants.REQUEST_SECURITY_TOKEN_RESPONSE_LN);
+    /**
+     * <code>ds:Signature</code> as defined by XML Signature specification.
+     */
+    protected static final QName SIGNATURE =
+        new QName(WSConstants.SIG_NS, WSConstants.SIG_LN);
+    /**
+     * <code>xenc:ReferenceList</code> as defined by XML Encryption specification,
+     */
+    protected static final QName REFERENCE_LIST =
+        new QName(WSConstants.ENC_NS, WSConstants.REF_LIST_LN);
+
+    protected static final QName SCT = SecurityContextToken.TOKEN;
+
+    protected HashMap configurator = new HashMap();
+
+    protected String trustPropFile = null;
+
+    protected boolean verifyTrust = false;
+
+    protected WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+
+    static {
+        org.apache.xml.security.Init.init();
+    }
+
+    public ConversationEngine(HashMap config) {
+
+        this.configurator = config;
+        //TODO :: Move this out of here.
+        Boolean bool = null;
+        if ((bool =
+            (Boolean) configurator.get(ConvHandlerConstants.VERIFY_TRUST))
+            == null) {
+
+        } else {
+            this.verifyTrust = bool.booleanValue();
+            if (verifyTrust) {
+                this.trustPropFile =
+                    (String) configurator.get(
+                        ConvHandlerConstants.TRUST_ENGINE_PROP);
+            }
+        }
+    }
+
+    /**
+     * This method is extracted from org.apache.ws.security.SecurityEngine
+     *
+     * @param doc
+     * @param actor
+     * @param cb
+     * @return
+     * @throws ConversationException
+     */
+
+    public Vector processSecConvHeader(
+        Document doc,
+        String actor,
+        DerivedKeyCallbackHandler dkcb,
+        String callback)
+        throws ConversationException {
+
+        doDebug = log.isDebugEnabled();
+        if (doDebug) {
+            log.debug("enter processSecurityHeader()");
+        }
+
+        if (actor == null) {
+            actor = "";
+        }
+        NodeList list =
+            doc.getElementsByTagNameNS(
+                WSConstants.WSSE_NS,
+                WSConstants.WSSE_LN);
+        int len = list.getLength();
+        if (len == 0) { // No Security headers found
+            return null;
+        }
+        if (doDebug) {
+            log.debug("Found WS-Security header(s): " + len);
+        }
+        Element elem = null;
+        Attr attr = null;
+        String headerActor = null;
+        SOAPConstants sc =
+            WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+        Vector convResult = new Vector();
+
+        for (int i = 0; i < len; i++) {
+            elem = (Element) list.item(i);
+            attr =
+                elem.getAttributeNodeNS(
+                    sc.getEnvelopeURI(),
+                    sc.getRoleAttributeQName().getLocalPart());
+            if (attr != null) {
+                headerActor = attr.getValue();
+            }
+            if ((headerActor == null)
+                || (headerActor.length() == 0)
+                || headerActor.equalsIgnoreCase(actor)
+                || headerActor.equals(sc.getNextRoleURI())) {
+                if (doDebug) {
+                    log.debug(
+                        "Processing WS-Security header for '"
+                            + actor
+                            + "' actor.");
+                }
+
+                try {
+                    convResult = processConvHeader(elem, doc, dkcb, callback);
+                } catch (WSSecurityException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                } catch (ConversationException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+
+            }
+        }
+        return convResult;
+    }
+
+    /**
+     * @param doc
+     * @param dkcbHandler
+     * @throws ConversationException
+     */
+
+    protected Vector processConvHeader(
+        Element securityHeader,
+        Document doc,
+        DerivedKeyCallbackHandler dkcbHandler,
+        String callback)
+        throws ConversationException, WSSecurityException {
+
+        long t0 = 0, t1 = 0, t2 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+
+        NodeList list = securityHeader.getChildNodes();
+        int len = list.getLength();
+        Node elem;
+        String localName = null;
+        String namespace = null;
+
+        if (tlog.isDebugEnabled()) {
+            t1 = System.currentTimeMillis();
+        }
+
+        Vector returnResults = new Vector();
+
+        for (int i = 0; i < len; i++) {
+            elem = list.item(i);
+            if (elem.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
+
+            if (el.equals(REQUESTED_SECURITY_TOKEN_RESPONSE)) {
+                if (doDebug) {
+                    log.debug("Found RequestedSecurityTokenResponse element");
+                }
+
+                returnResults.add(
+                    this.handleRequestedSecurityTokenResponse(
+                        (Element) elem,
+                        dkcbHandler,
+                        callback));
+
+            } else if (el.equals(SIGNATURE)) {
+                if (doDebug) {
+                    log.debug("Found Signature element");
+                }
+
+                ConvEngineResult convResult =
+                    this.VerifySignature((Element) elem, dkcbHandler);
+                returnResults.add(convResult);
+            } else if (el.equals(REFERENCE_LIST)) {
+                if (doDebug) {
+                    log.debug("Found Reference List element");
+
+                }
+                Vector tmpVec =
+                    handleReferenceList((Element) elem, dkcbHandler);
+                for (int j = 0; j < tmpVec.size(); j++) {
+                    returnResults.add(tmpVec.get(j));
+                }
+            } else if (el.equals(SCT)) {
+                SecurityContextToken sct =
+                    new SecurityContextToken((Element) elem);
+                String uuid = sct.getIdentifier();
+                ConvEngineResult convResult =
+                    new ConvEngineResult(ConvEngineResult.SCT);
+                convResult.setUuid(uuid);
+                returnResults.add(convResult);
+            }
+
+        }
+        return returnResults;
+    }
+
+    public ConvEngineResult handleRequestedSecurityTokenResponse(
+        Element eleSTRes,
+        DerivedKeyCallbackHandler dkcbHandler,
+        String callback)
+        throws ConversationException {
+        String uuid = null;
+        RequestSecurityTokenResponse stRes = null;
+
+        try {
+            if (verifyTrust) {
+                TrustEngine trstEngine = new TrustEngine(this.trustPropFile);
+                
+                // TODO :: Verify trust......
+                System.out.println("...........Verifying trust.........");
+
+            }
+
+            //Now trust is verified.
+
+            stRes = new RequestSecurityTokenResponse(eleSTRes, true);
+            SecurityContextToken SCT =
+                stRes.getRequestedSecurityToken().getSct();
+            uuid = SCT.getIdentifier();
+            RequestedProofToken proofToken = stRes.getRequestedProofToken();
+            //TODO:: romove the hard coded decryption
+
+            proofToken.doDecryption(callback, this.loadDecryptionCrypto());
+
+            SecurityContextInfo scInfo = null;
+            scInfo = new SecurityContextInfo(SCT, proofToken, 1);
+
+            dkcbHandler.addSecurtiyContext(uuid, scInfo);
+                dkcbHandler.setDerivedKeyLength(
+                    uuid,
+                    ((Long) configurator.get(ConvHandlerConstants.KEY_LEGNTH))
+                        .longValue());
+
+            log.debug(" Done SecurityToekenResponse Handled");
+            ConvEngineResult res =
+                new ConvEngineResult(ConvEngineResult.SECURITY_TOKEN_RESPONSE);
+            res.setUuid(uuid);
+            return res;
+
+        } catch (WSTrustException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new ConversationException("");
+        } catch (WSSecurityException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new ConversationException("");
+        }
+    }
+
+    private ConvEngineResult VerifySignature(
+        Element elem,
+        DerivedKeyCallbackHandler dkcbHandler)
+        throws ConversationException {
+        ConvEngineResult convResult = null;
+        XMLSignature sig = null;
+//      System.out.println("******** at VerifySignature");
+//		ByteArrayOutputStream os = new ByteArrayOutputStream();
+//		XMLUtils.outputDOM(elem, os, true);
+//		String osStr = os.toString();
+//		System.out.println(osStr);
+        try {
+            sig = new XMLSignature(elem, null);
+        } catch (XMLSignatureException e2) {
+            throw new ConversationException("noXMLSig");
+        } catch (XMLSecurityException e2) {
+            throw new ConversationException("noXMLSig");
+        } 
+        String sigMethodURI = sig.getSignedInfo().getSignatureMethodURI();
+        //verifying the sinature
+        if (sigMethodURI.equals(XMLSignature.ALGO_ID_MAC_HMAC_SHA1)) {
+
+            try {
+                //sign.verifiyXMLHMac_SHA1_Signarue(sig, dkcbHandler);
+                convResult =
+                    this.verifiyXMLHMac_SHA1_Signarue(sig, dkcbHandler);
+            } catch (WSSecurityException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+        } else {
+            throw new ConversationException("Failed");
+        }
+        return convResult;
+    }
+
+    /**
+     * This method is extracted from WSSecurityEngine.
+     * <p/>
+     * Dereferences and decodes encrypted data elements.
+     */
+    private Vector handleReferenceList(
+        Element elem,
+        DerivedKeyCallbackHandler dkcbHandler)
+        throws WSSecurityException {
+        Vector results = new Vector();
+        Document doc = elem.getOwnerDocument();
+        Node tmpE = null;
+        for (tmpE = elem.getFirstChild();
+            tmpE != null;
+            tmpE = tmpE.getNextSibling()) {
+            if (tmpE.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            if (!tmpE.getNamespaceURI().equals(WSConstants.ENC_NS)) {
+                continue;
+            }
+            if (tmpE.getLocalName().equals("DataReference")) {
+                String dataRefURI = ((Element) tmpE).getAttribute("URI");
+                ConvEngineResult convRes =
+                    decryptDataRef(doc, dataRefURI, dkcbHandler);
+                results.add((Object) convRes);
+            } else if (tmpE.getLocalName().equals("KeyReference")) {
+                String keyRefURI = ((Element) tmpE).getAttribute("URI");
+            }
+        }
+        return results;
+    }
+
+    private ConvEngineResult decryptDataRef(
+        Document doc,
+        String dataRefURI,
+        DerivedKeyCallbackHandler dkcbHandler)
+        throws WSSecurityException {
+
+        log.debug("ConversationEngine :: Found data refernce: " + dataRefURI);
+
+        ConvEngineResult convResult = null;
+        /*
+         * Look up the encrypted data. First try wsu:Id="someURI". If no such Id then
+         * try the generic lookup to find Id="someURI"
+         */
+        Element encBodyData = null;
+        if ((encBodyData =
+            WSSecurityUtil.getElementByWsuId(
+                doc,
+                dataRefURI))
+            == null) {
+            encBodyData = WSSecurityUtil.getElementByGenId(doc, dataRefURI);
+        }
+        if (encBodyData == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY,
+                "dataRef",
+                new Object[] { dataRefURI });
+        }
+
+        Element tmpE = null;
+        log.debug(
+            "ConversationEngine :: Going to figure out the key to decrypt");
+        byte[] decryptedBytes = null;
+
+        /*
+         * Decryption is performed in 3 major steps
+         */
+
+        //Step 1 : Get the key from SecurityTokenReference.
+
+        log.debug(
+            "ConversationEngine:: Going to look for SecurityTokenReference");
+
+        if ((tmpE =
+            (Element) WSSecurityUtil.findElement(
+                (Node) encBodyData,
+                "SecurityTokenReference",
+                WSConstants.WSSE_NS))
+            != null) {
+            SecurityTokenReference secRef =
+                new SecurityTokenReference(
+                    tmpE);
+
+            try {
+                convResult =
+                    this.handleSecurityTokenReference(secRef, dkcbHandler);
+                decryptedBytes = convResult.getKeyAssociated();
+            } catch (ConversationException e2) {
+                // TODO Auto-generated catch block
+                e2.printStackTrace();
+            }
+
+        } else {
+            //TODO:: Provide more info
+            throw new WSSecurityException(WSSecurityException.FAILURE);
+        }
+
+        // Step 2 :: Now figure out the encryption algorithm
+        String symEncAlgo = getEncAlgo(encBodyData);
+        SecretKey symmetricKey =
+            WSSecurityUtil.prepareSecretKey(symEncAlgo, decryptedBytes);
+
+
+        // Step 3 :: initialize Cipher ....
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(symEncAlgo);
+            xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
+        } catch (XMLEncryptionException e1) {
+            throw new WSSecurityException(
+                WSSecurityException.UNSUPPORTED_ALGORITHM,
+                null,
+                null,
+                e1);
+        }
+
+
+
+		WSSecurityEngine eng = new WSSecurityEngine();
+        boolean content = this.isContent(encBodyData);//Whether content encryption or element encryption
+
+        if (content) {
+            encBodyData = (Element) encBodyData.getParentNode();
+        }else{
+        	System.out.println("Not content:-)");
+        }
+
+        try {
+            xmlCipher.doFinal(doc, encBodyData, content);
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENC_DEC,
+                null,
+                null,
+                e);
+        }
+        return convResult;
+    }
+
+    public ConvEngineResult handleSecurityTokenReference(
+        SecurityTokenReference secRef2DkToken,
+        DerivedKeyCallbackHandler dkcbHandler)
+        throws ConversationException {
+
+        if (secRef2DkToken.containsReference()) {
+            Reference ref = null;
+            try {
+                ref = secRef2DkToken.getReference();
+            } catch (WSSecurityException e1) {
+                e1.printStackTrace();
+                throw new ConversationException(e1.getMessage());
+            }
+
+            String valueType = ref.getValueType();
+            //  System.out.println("ref.getURI()" + ref.getURI());
+
+            //If the reference type is a derived key token
+            if (valueType.equals(ConversationConstants.TOKEN_TYPE_DERIVED_KEY_TOKEN)) {
+            	//Get hold of the DerivedKeyToken 'Element'
+                Element ele =
+                    WSSecurityUtil.getElementByWsuId(
+                        secRef2DkToken.getElement().getOwnerDocument(),
+                        ref.getURI());
+                if (ele == null) {
+                    throw new ConversationException("Cannot find  referenced Derived Key");
+                }
+                String uuid = null;
+                DerivedKeyToken dkToken = null;
+                try {
+                    dkToken = new DerivedKeyToken(ele);  //Cover the 'Element' into 'DerivedKeyToken' object
+                    if (dkToken.getSecuityTokenReference() == null) {
+                        //if dkToken doesn't have a STR find a SecurityContextToken in the SOAP Envelope
+                        SecurityContextToken secContextTk =
+                            ConversationUtil.getSCT(dkToken);
+                        uuid = secContextTk.getIdentifier();
+                        log.debug(
+                            "ConversationEngine :: The uuid is found " + uuid);
+                        DerivedKeyInfo dkInfo = new DerivedKeyInfo(dkToken);
+                        dkcbHandler.addDerivedKey(uuid, dkInfo);
+                    } else { ///i.e. dkToken has a STR
+                        SecurityTokenReference str2Base =
+                            dkToken.getSecuityTokenReference();
+                        if (str2Base.containsReference()) {
+                            Reference ref2Base = str2Base.getReference();
+
+                            if (ref2Base
+                                .getValueType()
+                                .equals("http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID")) {
+                                /* ok now I have a SAML token. What should I do ?
+                                 * -Decrypt the secret.
+                                 * -create tempUUID
+                                 * -add the scTInfo into dkcbHandler
+                                 * -add the derived key token to dkcbHandler.
+                                 */
+                               uuid = ref2Base.getURI();
+                     		   if(dkcbHandler.getSession(uuid)==null){
+						   	       byte[] key = handleSAML(ref2Base.getElement().getOwnerDocument(), uuid);
+								   System.out.println("I am here :-)");
+								   SecurityContextInfo sctInfo = new SecurityContextInfo(
+																	   uuid,
+																	   key,
+																	   1);
+								   dkcbHandler.addSecurtiyContext(
+																	   uuid,
+																	   sctInfo);
+							   }
+									DerivedKeyInfo dkInfo = new DerivedKeyInfo(dkToken);
+									dkcbHandler.addDerivedKey(uuid, dkInfo);
+                            }
+
+
+
+                            //TODO :: Add other tokens else if
+                        } else if(str2Base.containsKeyIdentifier()){
+                        	Element elem = str2Base.getFirstElement();
+                        	//.getKeyIdentifier()System.out.println("KeyIdentifier :: He ehee ........");
+							String value = elem.getAttribute("ValueType");
+							if("http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID".equals(value)){
+								uuid = ((Text)elem.getChildNodes().item(0)).getNodeValue();
+								if(dkcbHandler.getSession(uuid)==null){
+									   byte[] key = handleSAML(elem.getOwnerDocument(), uuid);
+									   System.out.println("UUID of SAML is"+uuid);
+									   SecurityContextInfo sctInfo = new SecurityContextInfo(
+																									   uuid,
+																									   key,
+																									   1);
+									   dkcbHandler.addSecurtiyContext(uuid,sctInfo);
+								}
+								DerivedKeyInfo dkInfo = new DerivedKeyInfo(dkToken);
+								dkcbHandler.addDerivedKey(uuid, dkInfo);
+							}
+
+                        }else{
+                            throw new ConversationException("Cannot handle this type of security token reference: " + dkToken.getSecuityTokenReference().getReference().getValueType());
+                        }
+                    } //////end :if dkToken has a STR
+                    //TODO :: Ask ruchith to throw correct exception
+                } catch (WSSecurityException e2) {
+                    e2.printStackTrace();
+                } catch (ConversationException e2) {
+                    e2.printStackTrace();
+                }
+
+                String identifier =
+                    ConversationUtil.generateIdentifier(uuid, dkToken.getID());
+                WSPasswordCallback pwCb =
+                    new WSPasswordCallback(
+                        identifier,
+                        WSPasswordCallback.UNKNOWN);
+                Callback[] callbacks = new Callback[1];
+                callbacks[0] = pwCb;
+                try {
+                    dkcbHandler.handle(callbacks);
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                byte[] arr = pwCb.getKey();
+                ConvEngineResult res =
+                    new ConvEngineResult(ConvEngineResult.ENCRYPT_DERIVED_KEY);
+                res.setKeyAssociated(arr);
+                return res;
+            } else {
+                throw new ConversationException("ConversationEngine :: SecurityTokenRerence doesn't contain DerivedKeys");
+            }
+        } else {
+            throw new ConversationException("ConversationEngine ::SecurityTokenRerence doesn't contain refernce");
+        }
+
+    }
+
+    /**
+     * @param sig - XML Signature obeject containing the XMLSignature element.
+     * @param cb  - Callback handler to get the symmetric key.
+     * @return
+     */
+    private ConvEngineResult verifiyXMLHMac_SHA1_Signarue(
+        XMLSignature sig,
+        DerivedKeyCallbackHandler dkcbHandler)
+        throws WSSecurityException {
+
+        log.debug("Verifying HMAC-SHA1 Signature......");
+
+        String userName = null;
+        long t0 = 0, t1 = 0, t2 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+        ConvEngineResult convResult = null;
+        if (sig == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY_TOKEN,
+                "XMLSignature object is null");
+        } /* Following lines of code - upto WSDocInfoStore.lookup(docHash) is copied
+                                  * from the verifyXMLSignature() method.
+                                  *
+                                  */
+
+        sig.addResourceResolver(
+            EnvelopeIdResolver.getInstance());
+        KeyInfo info = sig.getKeyInfo();
+        if (info == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY,
+                "unsupportedKeyInfo");
+        }
+        Node node =
+            WSSecurityUtil.getDirectChild(
+                info.getElement(),
+                SecurityTokenReference.SECURITY_TOKEN_REFERENCE,
+                WSConstants.WSSE_NS);
+        if (node == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY,
+                "unsupportedKeyInfo");
+        }
+        SecurityTokenReference secRef =
+            new SecurityTokenReference(
+                (Element) node);
+        Document docSig = sig.getDocument();
+        int docHash = docSig.hashCode();
+        if (doDebug) {
+            log.debug("XML Verify doc: " + docHash);
+        } /*
+                                  * Her we get some information about the document that is being processed,
+                                  * in partucular the crypto implementation, and already detected BST that
+                                  * may be used later during dereferencing.
+                                  */
+        WSDocInfo wsDocInfo = WSDocInfoStore.lookup(docHash);
+        if (secRef.containsReference()) {
+            Element token =
+                secRef.getTokenElement(sig.getDocument(), wsDocInfo);
+            /* check token type: We support Derivedkey tokens now.
+             * We will support security context tokens.
+             */
+            QName el = new QName(token.getNamespaceURI(), token.getLocalName());
+            if (el.equals(DERIVEDKEY_TOKEN)) {
+                DerivedKeyToken dkToken = new DerivedKeyToken(token);
+                DerivedKeyInfo dkInfo = null;
+
+				String uuid = null;
+
+                try {
+					if (dkToken.getSecuityTokenReference() == null) {
+						//if dkToken doesn't have a STR
+						SecurityContextToken secContextTk =
+							ConversationUtil.getSCT(dkToken);
+						uuid = secContextTk.getIdentifier();
+						log.debug(
+							"ConversationEngine :: The uuid is found " + uuid);
+						dkInfo = new DerivedKeyInfo(dkToken);
+						dkcbHandler.addDerivedKey(uuid, dkInfo);
+					} else { ///i.e. dkToken has a STR
+						SecurityTokenReference str2Base =
+							dkToken.getSecuityTokenReference();
+						if (str2Base.containsReference()) {
+							Reference ref2Base = str2Base.getReference();
+                          //TODO:: Find where can I find the constants.
+							if (ref2Base
+								.getValueType()
+								.equals("http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID")) {
+								/* ok now I have a SAML token. What should I do ?
+								 * -Decrypt the secret.
+								 * -create tempUUID
+								 * -add the scTInfo into dkcbHandler
+								 * -add the derived key token to dkcbHandler.
+								 */
+								uuid = ref2Base.getURI();
+								if(dkcbHandler.getSession(uuid)==null){
+									byte[] key = handleSAML(docSig, uuid);
+									System.out.println("I am here :-)");
+									SecurityContextInfo sctInfo =
+									new SecurityContextInfo(
+										uuid,
+										key,
+										1);
+									dkcbHandler.addSecurtiyContext(
+										uuid,
+									sctInfo);
+								}
+									dkInfo = new DerivedKeyInfo(dkToken);
+									dkcbHandler.addDerivedKey(uuid, dkInfo);
+								}
+						} else if(str2Base.containsKeyIdentifier()){
+													Element elem = str2Base.getFirstElement();
+													//.getKeyIdentifier()System.out.println("KeyIdentifier :: He ehee ........");
+													String value = elem.getAttribute("ValueType");
+								if("http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID".equals(value)){
+									uuid = ((Text)elem.getChildNodes().item(0)).getNodeValue();
+									if(dkcbHandler.getSession(uuid)==null){
+									   byte[] key = handleSAML(elem.getOwnerDocument(), uuid);
+									   System.out.println("UUID of SAML is"+uuid);
+									   SecurityContextInfo sctInfo = new SecurityContextInfo(uuid,key,1);
+									   dkcbHandler.addSecurtiyContext(uuid,sctInfo);
+							    }
+								dkInfo = new DerivedKeyInfo(dkToken);
+								dkcbHandler.addDerivedKey(uuid, dkInfo);
+								}
+
+						} else {
+							throw new ConversationException("Don't know how to process here");
+						}
+
+					}
+                //String uuid = "aNewUuid";
+                String dkId = dkToken.getID();
+                userName = ConversationUtil.generateIdentifier(uuid, dkId);
+                convResult =
+                    new ConvEngineResult(ConvEngineResult.SIGN_DERIVED_KEY);
+                    dkcbHandler.addDerivedKey(uuid, dkInfo);
+                    log.debug(
+                        "ConversationEngine: added for signature varification. uuil:"
+                            + uuid
+                            + " id:"
+                            + dkId);
+                } catch (ConversationException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                //TODO :: Ask ruchith to throw correct exception
+				} catch (WSSecurityException e2) {
+					// TODO Auto-generated catch block
+					e2.printStackTrace();
+				}
+
+
+            } else if (el.equals(SCT_TOKEN)) {
+                throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY,
+                    "SCT is not Yet supported",
+                    new Object[] { el.toString()});
+            } else {
+                throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY,
+                    "unsupportedToken",
+                    new Object[] { el.toString()});
+            }
+
+            if (tlog.isDebugEnabled()) {
+                t1 = System.currentTimeMillis();
+            }
+
+            try {
+                // get the key from the callback handler
+                WSPasswordCallback callbacks[] =
+                    {
+                         new WSPasswordCallback(
+                            userName,
+                            WSPasswordCallback.UNKNOWN)};
+                try {
+                    dkcbHandler.handle(callbacks);
+                } catch (UnsupportedCallbackException e) {
+                    e.printStackTrace();
+                    throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE,
+                        "password call back failed",
+                        new Object[] { e.toString()});
+                } // get the key and check whether it is null
+                byte[] keyBytes = callbacks[0].getKey();
+                if (keyBytes == null) {
+                    throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY,
+                        "password call bac in DerivedKeyTokenHandler failed");
+                }
+
+                convResult.setKeyAssociated(keyBytes);
+                //System.out.println(new String(keyBytes));
+                SecretKey symetricKey =
+                    new SecretKeySpec(
+                        keyBytes,
+                        XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
+                if (sig.checkSignatureValue(symetricKey)) {
+                    if (tlog.isDebugEnabled()) {
+                        t2 = System.currentTimeMillis();
+                        tlog.debug(
+                            "Verify: total= "
+                                + (t2 - t0)
+                                + ", Find-the token refernced by wsse:Reference= "
+                                + (t1 - t0)
+                                + ", password call back & verify= "
+                                + (t2 - t1));
+                    }
+
+                } else {
+                    throw new WSSecurityException(
+                        WSSecurityException.FAILED_CHECK);
+                }
+            } catch (XMLSignatureException e1) {
+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+            }
+
+        }
+
+        return convResult;
+    }
+
+    /**
+     * Extracted from WSSecurityEngine.
+     *
+     * @param encBodyData
+     * @return
+     * @throws WSSecurityException
+     */
+    private String getEncAlgo(Node encBodyData) throws WSSecurityException {
+        Element tmpE =
+            (Element) WSSecurityUtil.findElement(
+                encBodyData,
+                "EncryptionMethod",
+                WSConstants.ENC_NS);
+        String symEncAlgo = null;
+        if (tmpE != null) {
+            symEncAlgo = tmpE.getAttribute("Algorithm");
+        }
+        if (symEncAlgo == null) {
+            throw new WSSecurityException(
+                WSSecurityException.UNSUPPORTED_ALGORITHM,
+                "noEncAlgo");
+        }
+        if (doDebug) {
+            log.debug("Sym Enc Algo: " + symEncAlgo);
+        }
+        return symEncAlgo;
+    } //TODO :: Remove this. Temporary method.
+
+
+	private Crypto loadDecryptionCrypto() {
+			Crypto crypto = null;
+			String encPropFile = (String)configurator.get(WSHandlerConstants.DEC_PROP_FILE);
+			crypto = CryptoFactory.getInstance(encPropFile);
+			return crypto;
+		}
+
+    /**
+     * This method will be scrapped after the re-architecture.
+     * Not so elegant work-around.
+     *
+     */
+    private byte[] handleSAML(Document doc, String assertionId) throws ConversationException{
+
+    	try {
+            Crypto crypto = this.loadDecryptionCrypto();
+            //get the security header block
+            //get the saml assertion
+
+            Element ele=WSSecurityUtil.findWsseSecurityHeaderBlock(doc, doc.getDocumentElement(), false);
+            Element samEle =(Element)WSSecurityUtil.getDirectChild(ele, "Assertion", "urn:oasis:names:tc:SAML:1.0:assertion" );
+//            SAMLAssertion assertion = new SAMLAssertion(samEle);
+//
+//            Iterator itr = assertion.getStatements();
+//
+//           	SAMLAuthenticationStatement auth = (SAMLAuthenticationStatement)itr.next();
+//           	Element eleEnc = auth.getSubject().getConfirmationData();
+//
+
+			Element eleEnc = (Element)samEle.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#","EncryptedKey").item(0);
+            String cb = (String)this.configurator.get(WSHandlerConstants.PW_CALLBACK_CLASS);
+
+            CallbackHandler cbHandler = null;
+			if (cb != null) {
+				Class cbClass = null;
+					try {
+						cbClass = Loader.loadClass(cb);
+				         cbHandler = (CallbackHandler) cbClass.newInstance();
+
+					} catch (ClassNotFoundException e) {
+						throw new ConversationException("Cannot find passwordcallback");
+					} catch (InstantiationException e2) {
+						// TODO Auto-generated catch block
+						e2.printStackTrace();
+				  	} catch (IllegalAccessException e2) {
+						// TODO Auto-generated catch block
+						e2.printStackTrace();
+					}
+
+			}else{
+				throw new ConversationException("Cannot find passwordcallback");
+			}
+
+            EncryptedKeyProcessor processor = new EncryptedKeyProcessor();
+            processor.handleEncryptedKey(eleEnc, cbHandler, crypto);
+            byte[] key = processor.getDecryptedBytes();
+
+            return key;
+
+    	}catch (WSSecurityException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+			throw new ConversationException("Cannot find passwordcallback");
+		}
+
+    }
+   /**
+    *
+    * Taken from WSSecurityEngine
+    *
+    * @param encBodyData
+    * @return
+    */
+    private boolean isContent(Node encBodyData) {
+        /*
+         * Depending on the encrypted data type (Content or Element) the encBodyData either
+         * holds the element whose contents where encrypted, e.g. soapenv:Body, or the
+         * xenc:EncryptedData element (in case of Element encryption). In either case we need
+         * to get the xenc:EncryptedData element. So get it. The findElement method returns
+         * immediatly if its already the correct element.
+         * Then we can get the Type attribute.
+         */
+
+        Element tmpE = (Element) WSSecurityUtil.findElement(encBodyData,
+                "EncryptedData", WSConstants.ENC_NS);
+        String typeStr = null;
+        boolean content = true;
+        if (tmpE != null) {
+            typeStr = tmpE.getAttribute("Type");
+        }
+        if (typeStr != null) {
+            content = typeStr.equals(WSConstants.ENC_NS + "Content") ? true : false;
+        }
+        return content;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationException.java b/src/org/apache/ws/sandbox/security/conversation/ConversationException.java
new file mode 100644
index 0000000..f96f9d1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+/**
+ * @todo Rewrite this to the way WSSecurityException work or some other proper way
+ */
+public class ConversationException extends Exception {
+
+    /**
+     * Constructor ConversationException
+     *
+     * @param message
+     */
+    public ConversationException(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationManager.java b/src/org/apache/ws/sandbox/security/conversation/ConversationManager.java
new file mode 100644
index 0000000..d7f43d5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationManager.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.token.DerivedKeyToken;
+import org.apache.ws.security.message.EnvelopeIdResolver;
+import org.apache.ws.security.message.WSEncryptBody;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.TransformationException;
+import org.apache.xml.security.transforms.Transforms;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.security.auth.callback.Callback;
+import java.util.Vector;
+
+/**
+ * This class helps handlers to carry on conversation.
+ * <p/>
+ * It performes functionalities
+ * 1) Adding derived Keys
+ * 2) Signing using derived keys
+ * 3) Encrypting using derive keys
+ * <p/>
+ * Actually the class is the collection of methods that are useful
+ * for carrying out conversation.
+ *
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ */
+public class ConversationManager {
+
+    private static Log log =
+            LogFactory.getLog(ConversationManager.class.getName());
+
+    private int generation = 0;
+    protected String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+    /**
+      * Adds Derived key tokens to the header of the SOAP message, given the
+      * following parameters.
+      * @param doc
+      * @param uuid
+      * @param dkcbHandler
+      * @param stRef2Base -SecurityTOkenReference to the token, from which the derived
+      *                    key is derived from
+      * @return
+      * @throws ConversationException
+      */
+     public DerivedKeyInfo createDerivedKeyToken(Document doc,
+                                             String uuid,
+                                             DerivedKeyCallbackHandler dkcbHandler,SecurityTokenReference stRef2Base, int keyLen )
+            throws ConversationException {
+        String genID = ConversationUtil.genericID();
+        
+        /*
+         * This metod is 4-step procedure. 
+         */
+         
+        // step 1 : Creating wsse:Reference to DerivedKeyToken
+        Reference ref = new Reference(doc);
+        ref.setURI("#" + genID);
+        ref.setValueType(ConversationConstants.TOKEN_TYPE_DERIVED_KEY_TOKEN);
+        SecurityTokenReference stRef = new SecurityTokenReference(doc);
+        stRef.setReference(ref);
+
+        WSSecurityUtil.setNamespace(stRef.getElement(),
+                WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        // step 2 :Create the DerriveToken
+        DerivedKeyToken dtoken = new DerivedKeyToken(doc);
+		if(stRef2Base != null){
+			dtoken.setSecuityTokenReference(doc, stRef2Base);
+		}
+        dtoken.setLabel(doc, "WS-SecureConversationWS-SecureConversation");
+        dtoken.setNonce(doc, ConversationUtil.generateNonce(128));
+        dtoken.setID(genID);
+		//System.out.println("Fix me here ....");
+		
+		if(keyLen!=-1){
+		   dtoken.setLength(doc,keyLen);
+		}
+        
+        //step 3 :add the derived key token infomation into the dkcbHandler
+        DerivedKeyInfo dkInfo = null;
+        try {
+            dkInfo = new DerivedKeyInfo(dtoken);
+            dkInfo.setSecTokRef2DkToken(stRef);
+            dkcbHandler.addDerivedKey(uuid, dkInfo);
+        } catch (WSSecurityException e) {
+            e.printStackTrace();
+            throw new ConversationException("ConversationManager:: Cannot add Derived key token to the envelope");
+        }
+
+               
+		return dkInfo;
+
+    }
+    
+    
+    public void addDkToken(Document doc, DerivedKeyInfo info){
+    	  DerivedKeyTokenAdder adder = new DerivedKeyTokenAdder();
+    	  adder.build(doc, info.getDkTok());
+    }		  
+
+    /**
+     * Manages derived key encryption.
+     *
+     * @param encUser
+     * @param actor
+     * @param mu
+     * @param doc
+     * @param secRef - SecurityTokenReference pointing to the derived Key
+     * @param dkcbHandler
+     * @throws ConversationException
+     */
+    public void performDK_ENCR(String encUser,
+                               String actor,
+                               boolean mu,
+                               Document doc,
+                               SecurityTokenReference secRef,
+                               DerivedKeyCallbackHandler dkcbHandler, Vector parts,
+                               String symAlgo)
+            throws ConversationException {
+        WSEncryptBody wsEncrypt = new WSEncryptBody(actor, mu);
+
+        /*
+         * Here we want to add a wsse:SecurityTokenReference element into <KeyInfo>.
+         * Rest is as same as EMBEDDED_KEYNAME , i.e. we want to encrypt the message
+         * using a symmetric key and the result would be an <EncryptedData> element.
+         * Steps are
+         * step 1: Adding SecurityTokenReference pointing to DkToken
+         * step 2: Adding the key into wsEncrypt
+         * step 3: Setting the user.
+         */
+        wsEncrypt.setKeyIdentifierType(WSConstants.EMBED_SECURITY_TOKEN_REF);
+		
+        /*
+         * step 1: Adding SecurityTokenReference pointing to DkToken.
+         */
+        wsEncrypt.setSecurityTokenReference(secRef);
+
+        /*
+         * step 2: Generating the key, and setting it in the the wsEncrypt
+         */
+        WSPasswordCallback pwCb =
+                new WSPasswordCallback(encUser, WSPasswordCallback.UNKNOWN);
+        Callback[] callbacks = new Callback[1];
+        callbacks[0] = (Callback) pwCb;
+
+        try {
+            dkcbHandler.handle(callbacks);
+        } catch (java.lang.Exception e) {
+            e.printStackTrace();
+            throw new ConversationException("ConversationManager :: PasswordCallback failed");
+        }
+
+        wsEncrypt.setKey(pwCb.getKey());
+        /*
+         * step 3: set the user.
+         */
+        wsEncrypt.setUserInfo(encUser);
+        
+        /*
+         * step 4 : Setting encryption parts
+         */
+         wsEncrypt.setParts(parts);  
+        
+         wsEncrypt.setSymmetricEncAlgorithm(symAlgo);
+         
+        try {
+            wsEncrypt.build(doc, null);
+        } catch (WSSecurityException e) {
+        	e.printStackTrace();
+            throw new ConversationException("ConversationManager :: Encryption: error during message processing");
+        }
+
+    }
+
+    /**
+     * Manages derived key signature.
+     *
+     * @param doc
+     * @param dkcbHandler
+     * @param uuid
+     * @param dkSigInfo
+     * @throws ConversationException
+     */
+    public void performDK_Sign(Document doc,
+                               DerivedKeyCallbackHandler dkcbHandler,
+                               String uuid,
+                               DerivedKeyInfo dkSigInfo, Vector parts)
+            throws ConversationException {
+        //            Signing....
+        //        HMAC_SignVerify sign = new HMAC_SignVerify();
+        String sigAlgo = XMLSignature.ALGO_ID_MAC_HMAC_SHA1;
+
+        String sigUser =
+                ConversationUtil.generateIdentifier(uuid, dkSigInfo.getId());
+        System.out.println("Signature user is ::"+sigUser);
+        WSPasswordCallback pwCb =
+                new WSPasswordCallback(sigUser, WSPasswordCallback.UNKNOWN);
+        Callback[] callbacks = new Callback[1];
+        callbacks[0] = (Callback) pwCb;
+
+        try {
+            dkcbHandler.handle(callbacks);
+        } catch (java.lang.Exception e) {
+            throw new ConversationException("ConversationManager :: Password callback failed");
+        }
+        try {
+            Reference ref = dkSigInfo.getSecTokRef2DkToken().getReference();
+            this.build(doc, ref, pwCb.getKey(), parts);
+        } catch (WSSecurityException e1) {
+            e1.printStackTrace();
+            throw new ConversationException("ConversationManager :: Error performing signature.");
+        }
+
+    }
+
+    /**
+     * The method is coded such that it can be plugged into WSSignEnvelope.
+     * Performs HMAC_SHA1 signature.
+     * needed.
+     *
+     * @param doc
+     * @param ref
+     * @param sk
+     * @param parts
+     * @return
+     * @throws WSSecurityException
+     */
+    public Document build(Document doc, Reference ref, byte[] sk, Vector parts)
+            throws WSSecurityException {
+        boolean doDebug = log.isDebugEnabled();
+
+        if (doDebug) {
+            log.debug("Beginning signing...");
+        }
+
+        if (ref == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidData",
+                    new Object[]{"For symmeric key signatures - Reference object must be provided"});
+        }
+
+        if (sk == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidData",
+                    new Object[]{"For symmeric key signatures - Reference object must be provided"});
+        }
+        String sigAlgo = XMLSignature.ALGO_ID_MAC_HMAC_SHA1;
+        log.debug("Key is "+new String(sk));
+
+        SecretKey sharedKey = new SecretKeySpec(sk, sigAlgo);
+
+        //TODO :: Check for the characteristics (eg: legnth of the key) of the key if it applies.
+
+        /*
+         * Gather some info about the document to process and store it for
+         * retrival
+         */
+        WSDocInfo wsDocInfo = new WSDocInfo(doc.hashCode());
+        Element envelope = doc.getDocumentElement();
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
+        Element securityHeader =
+                WSSecurityUtil.findWsseSecurityHeaderBlock(doc,
+                        doc.getDocumentElement(),
+                        true);
+
+        XMLSignature sig = null;
+        try {
+            sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
+        } catch (XMLSecurityException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    "noXMLSig");
+        }
+
+        KeyInfo info = sig.getKeyInfo();
+        String keyInfoUri = "KeyId-" + info.hashCode();
+        info.setId(keyInfoUri);
+
+        SecurityTokenReference secRef = new SecurityTokenReference(doc);
+        String strUri = "STRId-" + secRef.hashCode();
+        secRef.setID(strUri);
+
+        if (parts == null) {
+            parts = new Vector();
+            WSEncryptionPart encP =
+                    new WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),
+                            soapConstants.getEnvelopeURI(),
+                            "Content");
+            parts.add(encP);
+        }
+
+        /*
+         * The below "for" loop (which perform transforms) is
+         * copied from 
+         *        build(Document doc, Crypto crypto) method in
+         *            org.apache.ws.security.message.WSEncryptBody.java                  
+         */
+
+        Transforms transforms = null;
+
+        for (int part = 0; part < parts.size(); part++) {
+            WSEncryptionPart encPart = (WSEncryptionPart) parts.get(part);
+            String elemName = encPart.getName();
+            String nmSpace = encPart.getNamespace();
+
+            /*
+             * Set up the elements to sign. There are two resevered element
+             * names: "Token" and "STRTransform" "Token": Setup the Signature
+             * to either sign the information that points to the security token
+             * or the token itself. If its a direct reference sign the token,
+             * otherwise sign the KeyInfo Element. "STRTransform": Setup the
+             * ds:Reference to use STR Transform
+             *
+             */
+            try {
+                if (elemName.equals("Token")) {
+                    transforms = new Transforms(doc);
+                    transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    sig.addDocument("#" + keyInfoUri, transforms);
+                } else if (elemName.equals("STRTransform")) { // STRTransform
+                    Element ctx = createSTRParameter(doc);
+                    transforms = new Transforms(doc);
+                    transforms.addTransform(STRTransform.implementedTransformURI,
+                            ctx);
+                    sig.addDocument("#" + strUri, transforms);
+                } else {
+                    Element body =
+                            (Element) WSSecurityUtil.findElement(envelope,
+                                    elemName,
+                                    nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(WSSecurityException.FAILURE,
+                                "noEncElement",
+                                new Object[]{nmSpace + ", " + elemName});
+                    }
+                    transforms = new Transforms(doc);
+                    transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    sig.addDocument("#" + setWsuId(body), transforms);
+                }
+            } catch (TransformationException e1) {
+                throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                        "noXMLSig",
+                        null,
+                        e1);
+            } catch (XMLSignatureException e1) {
+                throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                        "noXMLSig",
+                        null,
+                        e1);
+            }
+        }
+
+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());
+
+        /*
+         * Prepending order
+         * -Append the signature element.
+         * -Apped the KeyInfo element
+         */
+        WSSecurityUtil.appendChildElement(doc,
+                securityHeader,
+                sig.getElement());
+
+        /*
+         * Put the "Reference object" into secRef in KeyInfo
+         */
+        secRef.setReference(ref);
+
+        info.addUnknownElement(secRef.getElement());
+
+        try {
+            sig.sign(sharedKey);
+        } catch (XMLSignatureException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null,
+                    null,
+                    e1);
+        }
+
+        if (doDebug) {
+            log.debug("Signing complete.");
+        }
+        return (doc);
+
+    }
+
+    /*
+     * Extracted from org.apache.ws.security.message.WSSignEnvelope.java
+     */
+    private Element createSTRParameter(Document doc) {
+        Element transformParam =
+                doc.createElementNS(WSConstants.WSSE_NS,
+                        WSConstants.WSSE_PREFIX + ":TransformationParameters");
+
+        WSSecurityUtil.setNamespace(transformParam,
+                WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        Element canonElem =
+                doc.createElementNS(WSConstants.SIG_NS,
+                        WSConstants.SIG_PREFIX + ":CanonicalizationMethod");
+
+        WSSecurityUtil.setNamespace(canonElem,
+                WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX);
+
+        canonElem.setAttributeNS(null,
+                "Algorithm",
+                Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+        transformParam.appendChild(canonElem);
+        return transformParam;
+    }
+
+    /*
+         * Extracted from org.apache.ws.security.message.WSSignEnvelope.java
+         */
+
+    protected String setWsuId(Element bodyElement) {
+        String prefix =
+                WSSecurityUtil.setNamespace(bodyElement,
+                        WSConstants.WSU_NS,
+                        WSConstants.WSU_PREFIX);
+        String id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id");
+        if ((id == null) || (id.length() == 0)) {
+            id = "id-" + Integer.toString(bodyElement.hashCode());
+            bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+        }
+        return id;
+    }
+
+    /**
+     * @param i
+     */
+    public void setGenerationInfo(int i) {
+        generation = i;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationSession.java b/src/org/apache/ws/sandbox/security/conversation/ConversationSession.java
new file mode 100644
index 0000000..27a3215
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationSession.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.info.SecurityContextInfo;
+import org.apache.ws.security.message.token.Reference;
+
+import java.util.Hashtable;
+
+/**
+ * @author Ruchith
+ * @version 1.0
+ */
+
+public class ConversationSession {
+
+    private Log log = LogFactory.getLog(ConversationSession.class.getName());
+
+    /**
+     * The security context info of this session
+     */
+    private SecurityContextInfo contextInfo;
+
+    /**
+     * The set of derived keys used in the session
+     * Here a Hashtable is used to list the derived keys by their id's
+     * This will be useful when selecting the relevant derived key in the key derivator
+     */
+    private Hashtable derivedKeys;
+
+    /**
+     * In cases where fixed length derived keys are to be used this will be set
+     * The value will be the number of bytes in the key
+     */
+    private long keyLength = -1;
+
+    /**
+     * This is the label used in key derivation
+     * If the label element is missing in the DerivedKeyToken element then the value
+     * of this element will be used in the derivation
+     * This value will be set by the DerivedKeyCallbackHandler
+     */
+    private String label;
+
+    /**
+     * Last time the session was used/modified
+     */
+    private long lastTouched;
+    
+    private boolean addBase2Message = true;
+    
+    private Reference ref2Base = null;
+
+    /**
+     * Creates a new conversation session for a gien security context
+     *
+     * @param contextInfo The security context info
+     */
+    public ConversationSession(SecurityContextInfo contextInfo) {
+        log.debug("Conversation Session : created. Identifier :" + contextInfo.getIdentifier());
+        this.contextInfo = contextInfo;
+        this.derivedKeys = new Hashtable();
+        touch();
+    }
+
+    /**
+     * Returns the security context info of this session
+     *
+     * @return the security context info of this session
+     */
+    public SecurityContextInfo getContextInfo() {
+        return this.contextInfo;
+    }
+
+    /**
+     * Returns the Hashtable of derived keys (<code>DerivedKeyInfo</code> obects) of
+     * this session
+     *
+     * @return A Hashtable of DerivedKeyInfo objects
+     */
+    public Hashtable getDerivedKeys() {
+        return this.derivedKeys;
+    }
+
+    /**
+     * This adds a derived key into the session
+     *
+     * @param dkInfo The info object of the relevant derived key
+     */
+    public void addDerivedKey(DerivedKeyInfo dkInfo) {
+        this.derivedKeys.put(dkInfo.getId(), dkInfo);
+        touch();
+    }
+
+    /**
+     * The label value to be used in the key derivation
+     *
+     * @return
+     */
+    public String getLabel() {
+        return this.label;
+    }
+
+    /**
+     * Set the label value to be used in key derivation
+     *
+     * @param label
+     */
+    public void setLabel(String label) {
+        this.label = label;
+        touch();
+    }
+
+    /**
+     * Get the length of the derived keys to be generated when fixed length keys are generated
+     *
+     * @return
+     */
+    public long getKeyLength() {
+        return keyLength;
+    }
+
+    /**
+     * Set the length of the derived key to be derived in this session
+     * This is set in the case where fixed length keys are used
+     *
+     * @param keyLength
+     */
+    public void setKeyLength(long keyLength) {
+        this.keyLength = keyLength;
+        touch();
+    }
+
+    /**
+     * Touch the session
+     */
+    public void touch() {
+        this.lastTouched = System.currentTimeMillis();
+    }
+
+    /**
+     * Returns the last time the session was used/modified
+     *
+     * @return Last touched time in milliseconds
+     */
+    public long getLastTouched() {
+        return this.lastTouched;
+    }
+
+    /**
+     * @return
+     */
+    public boolean isAddBase2Message() {
+        return addBase2Message;
+    }
+
+    /**
+     * @return
+     */
+    public Reference getRef2Base() {
+        return ref2Base;
+    }
+
+    /**
+     * @param b
+     */
+    public void setAddBase2Message(boolean b) {
+        addBase2Message = b;
+    }
+
+    /**
+     * @param reference
+     */
+    public void setRef2Base(Reference reference) {
+        ref2Base = reference;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/ConversationUtil.java b/src/org/apache/ws/sandbox/security/conversation/ConversationUtil.java
new file mode 100644
index 0000000..1e40f0f
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/ConversationUtil.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import org.apache.axis.encoding.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.token.DerivedKeyToken;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+public class ConversationUtil {
+
+    private static Log log = LogFactory.getLog(ConversationUtil.class.getName());
+
+    /**
+     * This is the seperator used in the identifier, which is set in the Callback class
+     * when it is used to get a key from the key derivator
+     * The identifier is the combination of the uuid of the security context and
+     * the nonce of the derived key token using which the key should be derived
+     */
+    private static final String ID_SEPARATER = "$$$$";
+
+    /**
+     * Genearets the nonce for a given bit length.
+     */
+    public static String generateNonce(int length) {
+        SecureRandom random = null;
+        try {
+            random = SecureRandom.getInstance("SHA1PRNG");
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        byte[] nonceValue = new byte[length/8];
+        random.nextBytes(nonceValue);
+        return Base64.encode(nonceValue);
+    }
+
+    /**
+     * @param identifier
+     * @return
+     * @see getUuidAndDerivedKeyTokenId()
+     */
+    public static String getDerivedKeyTokenId(String identifier) {
+        return getUuidAndDerivedKeyTokenId(identifier)[1];
+    }
+
+    /**
+     * @param identifier
+     * @return
+     * @see getUuidAndDerivedKeyTokenId()
+     */
+    public static String getUuid(String identifier) {
+        return getUuidAndDerivedKeyTokenId(identifier)[0];
+    }
+
+    /**
+     * This extracts the Uuid and the DerivedKeyTokenId from the identifier sent in
+     *
+     * @param identifier The identifier in uuid[ConvUtil.ID_SEPARATOR]nonce format
+     * @return A String arrasy of size 2 with uuid as the forst character and the nonce as the second
+     */
+    public static String[] getUuidAndDerivedKeyTokenId(String identifier) {
+        String[] returnValue = new String[2];
+        int uuidEnd = identifier.indexOf(ConversationUtil.ID_SEPARATER);
+
+        //Extract the uuid
+        returnValue[0] = identifier.substring(0, uuidEnd);
+
+        //Extract the DerivedKeyTokenId
+        returnValue[1] = identifier.substring(uuidEnd + ConversationUtil.ID_SEPARATER.length(), identifier.length());
+
+        return returnValue;
+    }
+
+    /**
+     * This generates the identifier string using the uuig and the nonce
+     *
+     * @param uuid  The uuid
+     * @param nonce The DerivedKeyTokenId
+     * @return generated identifier string
+     */
+    public static String generateIdentifier(String uuid, String derivedKeyTokenId) {
+        log.debug("ConversationUtil: Generating identifier. session id: " + uuid + ", dkt id: " + derivedKeyTokenId);
+        return uuid + ConversationUtil.ID_SEPARATER + derivedKeyTokenId;
+    }
+
+    public static String generateUuid() {
+        //This is wrong 
+        //Replace this with the proper code for Uuid generation
+        SecureRandom random = null;
+        try {
+            random = SecureRandom.getInstance("SHA1PRNG");
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        byte[] nonceValue = new byte[32];
+        random.nextBytes(nonceValue);
+        return Base64.encode(nonceValue);
+    }
+
+    /**
+     * Method genericID
+     *
+     * @return
+     */
+    public static String genericID() {
+        try {
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            int i = random.nextInt(Integer.MAX_VALUE);
+            return String.valueOf(i);
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * The method takes in a DerivedKetToken and returns the uuid of the corresponding SCT.
+     * There can be serveral cases.
+     * Case 1: If there is only one SCT in the owner docuemter it is the corresponding SCT
+     * Case 2: If there are two resolve them by Id
+     * Case 3: The corresponding SCT can be mentioned in properties as well.
+     *
+     * @param dkToken
+     * @return
+     */
+
+    public static SecurityContextToken getSCT(DerivedKeyToken dkToken) throws ConversationException {
+        //TODO : Case 2 and Case 3 throw proper exception
+        String uuid = null;
+        Document doc = dkToken.getElement().getOwnerDocument();
+        NodeList ndList = doc.getElementsByTagNameNS(ConversationConstants.WSC_NS, ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+        if (ndList.getLength() == 0) {
+            throw new ConversationException("Cannot find SCT");
+        }
+        try {
+            Element ele = (Element) ndList.item(0);
+            SecurityContextToken sct = new SecurityContextToken(ele);
+            return sct;
+        } catch (WSSecurityException e) {
+            //e.printStackTrace();
+            throw new ConversationException(e.getMessage());
+        }
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/DerivedKeyCallbackHandler.java b/src/org/apache/ws/sandbox/security/conversation/DerivedKeyCallbackHandler.java
new file mode 100644
index 0000000..3762ae0
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/DerivedKeyCallbackHandler.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.sandbox.security.conversation.message.info.SecurityContextInfo;
+import org.apache.ws.sandbox.security.conversation.sessions.SessionMonitor;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.util.Hashtable;
+
+public class DerivedKeyCallbackHandler implements CallbackHandler {
+
+    private static Log log = LogFactory.getLog(DerivedKeyCallbackHandler.class.getName());
+
+    /**
+     * The set of all the sessions
+     */
+    public static Hashtable conversationSessionTable = new Hashtable();
+
+    static {
+        log.debug("DerivedKeyCallbackHandler: Creating a session monitor");
+        try {
+            SessionMonitor sm = new SessionMonitor(conversationSessionTable);
+            sm.start();
+        } catch (ConversationException ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * @param uuid
+     * @param info
+     */
+    public static void addSecurtiyContext(String uuid, SecurityContextInfo info) {
+        //Create a new conversation session and add it to the session list
+        log.debug("DerivedKeyCallbackHandler: adding security context. Identifier: " + uuid);
+        conversationSessionTable.put(uuid, new ConversationSession(info));
+    }
+
+    /**
+     * In cases where fixed size derived keys are used; this method can be used to
+     * specifu the key size of a perticular session
+     *
+     * @param uuid      The identifier of the security context of the session
+     * @param keyLength the desired key size
+     * @throws ConversationException If the specified session is not available
+     *                               (There can be sevral reasons for this : expiration etc. will have to look into this)
+     */
+    public static void setDerivedKeyLength(String uuid, long keyLength) throws
+            ConversationException {
+        log.debug("DerivedKeyCallbackHandler: setting derived key length: " + keyLength);
+        ConversationSession session = (ConversationSession) conversationSessionTable.get(uuid);
+        if (session != null) {
+            session.setKeyLength(keyLength);
+        } else {
+            throw new ConversationException("The key size cannot be set: No such context/session");
+        }
+
+    }
+
+    //Dimuthu's COnversation manager requires this method
+    public static long getDerivedKeyLength(String uuid) throws ConversationException {
+        ConversationSession session = (ConversationSession) conversationSessionTable.get(uuid);
+        if (session != null) {
+            return session.getKeyLength();
+        } else {
+            throw new ConversationException("The key size cannot be retrieved: No such context/session");
+        }
+
+    }
+    
+    public static ConversationSession getSession(String uuid) throws ConversationException{
+		ConversationSession session = (ConversationSession) conversationSessionTable.get(uuid);
+				if (session != null) {
+					return session;
+				} else {
+					return null;
+				}
+
+    }
+
+    /**
+     * If the Label element is not available in a DerivedKeyToken element then
+     * the value given here will be use in the key derivation
+     * This value will be bound to the session. (There will be one label value for
+     * the session and it should not change during a derivation sequence
+     *
+     * @param uuid  The identifier of the security context of the session
+     * @param label The label value as a string
+     * @throws ConversationException If the specified session is not available
+     *                               (There can be sevral reasons for this : expiration etc. will have to look into this)
+     */
+    public static void setLabelForSession(String uuid, String label) throws
+            ConversationException {
+        ConversationSession session = (ConversationSession) conversationSessionTable.get(uuid);
+        if (session != null) {
+            session.setLabel(label);
+        } else {
+            throw new ConversationException("The key size cannot be set: No such context/session");
+        }
+    }
+    
+   
+    /**
+     * Adds a derived key into a session identified by the uuid
+     *
+     * @param uuid   The uuid of the session
+     * @param dkInfo The derived key as a <code>DerivedKeyInfo</code> object
+     * @throws ConversationException If the uuid is not in the list of sessions
+     *                               <b>This should be done here and not in the <code>handle</code> method since for example if the session is expired
+     *                               the request should not pass this point</b>
+     *                               In the scenario that we'r concerned here one party creates a derived key, encryps the message with it and sends
+     *                               The receiver should decrypt the message with that derived key. Therefore if the session is expired
+     *                               that fact will  be only evident at this point where, the derived key is being added into the relevant session.
+     */
+    public void addDerivedKey(String uuid, DerivedKeyInfo dkInfo) throws ConversationException {
+        log.debug("DerivedKeyCallbackHandler: Adding derived key Id: " + dkInfo.getId() + " to session: " + uuid);
+        ConversationSession convSess = (ConversationSession) conversationSessionTable.get(uuid);
+        if (convSess != null) {
+            ((ConversationSession) conversationSessionTable.get(uuid)).
+                    addDerivedKey(dkInfo);
+        } else {
+            throw new ConversationException("Session cannot be found");
+            /** @todo Handle this error properly  */
+            //This place can be reached
+            //1. If the session is expired
+            //2. If a wrong security context token is sent in (may be by some intruder)
+            //3. Will list more as and when I realize them :D
+        }
+    }
+
+    /**
+     * @param callbacks
+     * @throws UnsupportedCallbackException
+     */
+    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+
+            String keyId = pc.getIdentifer();
+            log.debug("DerivedKeyCallbackHandler: Requesting key for callback id: " + keyId);
+            //This will not be kept static
+            //Thisis instanciated all teh time
+            //So if the keying information(fixed size or not) changes during the session that can be supported
+            KeyDerivator kd = new KeyDerivator();
+            try {
+                pc.setKey(kd.generateKey(conversationSessionTable, keyId));
+            } catch (ConversationException ex1) {
+                ex1.printStackTrace();
+            } catch (WSSecurityException ex1) {
+                ex1.printStackTrace();
+            }
+
+//
+//      pc.setPassword("security");
+//      /** Field key */
+//      byte[] key = {
+//      (byte) 0x31, (byte) 0xfd, (byte) 0xcb, (byte) 0xda, (byte) 0xfb,
+//      (byte) 0xcd, (byte) 0x6b, (byte) 0xa8, (byte) 0xe6, (byte) 0x19,
+//      (byte) 0xa7, (byte) 0xbf, (byte) 0x51, (byte) 0xf7, (byte) 0xc7,
+//      (byte) 0x3e, (byte) 0x80, (byte) 0xae, (byte) 0x98, (byte) 0x51,
+//      (byte) 0xc8, (byte) 0x51, (byte) 0x34, (byte) 0x04};
+//      pc.setKey(key);
+//
+        }
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/DerivedKeyTokenAdder.java b/src/org/apache/ws/sandbox/security/conversation/DerivedKeyTokenAdder.java
new file mode 100644
index 0000000..aba2d20
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/DerivedKeyTokenAdder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import org.apache.ws.sandbox.security.conversation.message.token.DerivedKeyToken;
+import org.apache.ws.security.message.WSBaseMessage;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Class DerivedKeyTokenAdder
+ */
+public class DerivedKeyTokenAdder extends WSBaseMessage {
+
+    /**
+     * Method build
+     *
+     * @param doc
+     * @param dkToken
+     * @return
+     */
+    public Document build(Document doc,
+                          DerivedKeyToken dkToken) {    // throws Exception {
+
+        // log.debug("Begin add username token...");
+        Element securityHeader = insertSecurityHeader(doc);
+        WSSecurityUtil.prependChildElement(doc, securityHeader,
+                dkToken.getElement(),false);
+        return doc;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/KeyDerivator.java b/src/org/apache/ws/sandbox/security/conversation/KeyDerivator.java
new file mode 100644
index 0000000..4ba42b2
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/KeyDerivator.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.dkalgo.AlgoFactory;
+import org.apache.ws.sandbox.security.conversation.dkalgo.DerivationAlgorithm;
+import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+
+import java.util.Hashtable;
+
+/**
+ * @author Ruchith
+ * @version 1.0
+ */
+
+public class KeyDerivator {
+
+    private Log log = LogFactory.getLog(KeyDerivator.class.getName());
+
+    public byte[] generateKey(Hashtable sessionTable, String identifier) throws
+            WSSecurityException, ConversationException, WSSecurityException {
+
+        log.debug("KeyDerivator: Inside generate key");
+        String[] uuidAndDerivedKeyTokenId = ConversationUtil.
+                getUuidAndDerivedKeyTokenId(identifier);
+        //Get the session from teh session table
+        ConversationSession convSession = (ConversationSession) sessionTable.get(uuidAndDerivedKeyTokenId[0]);
+        log.debug("KeyDerivator: session found: " + uuidAndDerivedKeyTokenId[0]);
+        if (convSession != null) {
+            int freq = convSession.getContextInfo().getFrequency(); //Key generation frequency
+            if (freq == 0) { //If the frequency is zero then no need for key derivation
+                return convSession.getContextInfo().getSharedSecret();
+            } else { //Derived keys are required
+                return deriveKey(convSession, uuidAndDerivedKeyTokenId[1]);
+            }
+        } else {
+            /** @todo Check the list of expired sessions and figureout whether the session is expired or not */
+            throw new ConversationException("Conversation Session not found");
+        }
+    }
+
+    private byte[] deriveKey(ConversationSession convSession,
+                             String derivedKeyTokenId) throws
+            WSSecurityException, ConversationException {
+
+        //The derived key info object of the current derived key
+        DerivedKeyInfo dkInfo = (DerivedKeyInfo) convSession.getDerivedKeys().get(derivedKeyTokenId);
+        SecurityTokenReference secTokRef = dkInfo.getSecurityTokenReference();
+        log.debug("KeyDerivator: deriveKey: security token reference: " + secTokRef);
+//        if (secTokRef != null) {
+//            if (secTokRef.toString().equals("<wsse:SecurityTokenReference/>")) {//No security token reference
+//                log.debug("KeyDerivator: deriveKey: No security token refernece available");
+//                return deriveTokenFromContext(convSession, dkInfo);
+//            } else {
+//                String contextIdentifier = convSession.getContextInfo().getIdentifier();
+//
+//                String wsuId = secTokRef.getReference().getURI();
+//
+//                Element sctEle = WSSecurityUtil.getElementByWsuId(WSSConfig.getDefaultWSConfig(), secTokRef.getElement().getOwnerDocument(), wsuId);
+//
+//                try {
+//                    SecurityContextToken sct = new SecurityContextToken(sctEle);
+//                    if (contextIdentifier.equals(sct.getIdentifier()))
+//                        return deriveTokenFromContext(convSession, dkInfo);
+//                    else
+//                        throw new ConversationException("Derivation source cannot be determined");
+//                } catch (WSSecurityException secEx) {
+//                    /** @todo Supporting other tokens other than SCT as the derivation source */
+//                    //Here we should check whether it is some other type of a token
+//                    //E.g. DerivedKeyToken
+//                }
+//
+//                if (secTokRef.getReference().getURI().equals(contextIdentifier)) { //If the reference is to the SecurityContextToken
+//                    return deriveTokenFromContext(convSession, dkInfo);
+//                } else {
+//                    //Derive from some other security token other than the relevent security context
+//                    /** @todo Derive from some other security token other than the relevent security context
+//                     * For example this can be another DerivedKeyToken
+//                     * */
+//                    throw new ConversationException("KeyDerivator:  Deriving from some " +
+//                            "other security token other than the " +
+//                            "relevent security context: Not implemented :-(");
+//
+//                }
+//            }
+//        } else { //There is no SecurityTokenRefernece
+            log.debug("KeyDerivator: deriveKey: No security token refernece available");
+            return deriveTokenFromContext(convSession, dkInfo);
+  //      }
+
+    }
+
+    /**
+     * Derive the key from the related security context information
+     *
+     * @param convSession
+     * @param dkInfo
+     * @return
+     * @throws ConversationException
+     */
+    private byte[] deriveTokenFromContext(ConversationSession convSession,
+                                          DerivedKeyInfo dkInfo) throws
+            ConversationException {
+
+        log.debug("KeyDerivator: deriving key from contecxt :" + convSession.getContextInfo().getIdentifier() + " for dkt: " + dkInfo.getId());
+        byte[] secret = convSession.getContextInfo().getSharedSecret(); //Shared secret
+        String labelAndNonce = getLabelAndNonce(convSession, dkInfo); //Label and nonce
+        long keyLength = getKeyLength(convSession, dkInfo); //Length of the key to generated
+        int offset = getOffset(convSession, dkInfo);
+        DerivationAlgorithm derivationAlgo = AlgoFactory.getInstance(dkInfo.
+                getAlgorithm()); //Derivation algorithm
+        return derivationAlgo.createKey(secret, labelAndNonce, offset, keyLength);
+    }
+
+    /**
+     * The label+nonce value used for the seed in calculating the derived key
+     *
+     * @param convSession
+     * @param dkInfo
+     * @return relevan label+nonce
+     */
+    private String getLabelAndNonce(ConversationSession convSession,
+                                    DerivedKeyInfo dkInfo) throws
+            ConversationException {
+        String label, nonce;
+        if ((label = dkInfo.getLabel()) != null || (label = convSession.getLabel()) != null) {
+            if ((nonce = dkInfo.getNonce()) != null) {
+                log.debug("KeyDerivator: Inside get label and nocne : " + label + nonce);
+                return label + nonce;
+            } else {
+                throw new ConversationException("Nonce value not available");
+            }
+        } else {
+            throw new ConversationException("Label cannot be found");
+        }
+    }
+
+    /**
+     * This return teh key length of the derived key to be generated
+     *
+     * @param convSession
+     * @param dkInfo
+     * @return length of the key to be returned
+     * @throws ConversationException
+     */
+    private long getKeyLength(ConversationSession convSession,
+                              DerivedKeyInfo dkInfo) throws ConversationException {
+
+        long length;
+        if ((length = dkInfo.getLength()) != -1) { //If the length info is there in the token return it
+            log.debug("KeyDerivator: Inside get length: " + length);
+            return length;
+        } else if ((length = convSession.getKeyLength()) != -1) { //Get length info from the session
+            log.debug("KeyDerivator: Inside get length: " + length);
+            return length;
+        } else {
+            throw new ConversationException("Length information not available");
+        }
+    }
+
+    /**
+     * @param convSession
+     * @param dkInfo
+     * @return
+     * @throws ConversationException
+     */
+    private int getOffset(ConversationSession convSession, DerivedKeyInfo dkInfo) throws
+            ConversationException {
+        int offset = dkInfo.getOffset();
+        int generation = dkInfo.getGeneration();
+        long lengthFromDkInfo = dkInfo.getLength();
+
+        if (generation != -1 && offset != -1) { //If both generation and offset values are set
+            throw new ConversationException("Generation and Offset both cannot be used simultaneously: " +
+                    "Generation : " + generation +
+                    "Offset : " + offset);
+        } else if (convSession.getKeyLength() != -1) { //Session is configured to use fixed size keys
+            if (generation == -1){
+          		log.debug("Generation set to zero");
+          		generation = 0;   
+          return (int)convSession.getKeyLength() * generation;
+//                throw new ConversationException("Generation value is not avaliable (fixed size keys are used: " +
+//                        "Key size : " + convSession.getKeyLength() + ")");
+            }else{
+                return (int) convSession.getKeyLength() * generation;
+            }    
+        } else if (offset != -1) { //Fixed size keys are NOT used: The length and offset values should be available in the DKT
+            return offset;
+        } else if (generation != -1) { //Here length should be specified in the DKT
+            if (dkInfo.getLength() != -1)
+                return generation * (int) dkInfo.getLength();
+            else
+                throw new ConversationException("Length information not available");
+        } else {
+            return 0; //If generation and offset info are not available offset will be 0
+        }
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/dkalgo/AlgoFactory.java b/src/org/apache/ws/sandbox/security/conversation/dkalgo/AlgoFactory.java
new file mode 100644
index 0000000..8a5cbc5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/dkalgo/AlgoFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.dkalgo;
+
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+
+public class AlgoFactory {
+
+    /**
+     * This gives a DerivationAlgorithm instance from the default set of algorithms provided
+     *
+     * @param algorithm The algo identifier @see DeivationAlgorithm
+     * @return A derivatio algorithm
+     * @throws ConversationException If the specified algorithmis not available in
+     *                               default implementations
+     */
+    public static DerivationAlgorithm getInstance(String algorithm) throws
+            ConversationException {
+        if (algorithm.equals(DerivationAlgorithm.P_SHA_1)) {
+            return new P_SHA1();
+        } else {
+            throw new ConversationException("No such algorithm");
+        }
+    }
+
+    /** @todo instanciate an algo from a algo class externally specified  */
+//  public static DerivationAlgorithm getInstance(String algoClass, Properties properties) {
+//
+//  }
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/dkalgo/DerivationAlgorithm.java b/src/org/apache/ws/sandbox/security/conversation/dkalgo/DerivationAlgorithm.java
new file mode 100644
index 0000000..34c36b9
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/dkalgo/DerivationAlgorithm.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.dkalgo;
+
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+
+public interface DerivationAlgorithm {
+
+    /**
+     * This is the default key generation algotithm
+     */
+    public static final String P_SHA_1 = "http://schemas.xmlsoap.org/ws/2004/04/security/sc/dk/p_sha1";
+
+    /**
+     * @param secret
+     * @param labelAndNonce
+     * @param length
+     * @return
+     */
+    public byte[] createKey(byte[] secret, String labelAndNonce, int offset, long length) throws ConversationException;
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/dkalgo/P_SHA1.java b/src/org/apache/ws/sandbox/security/conversation/dkalgo/P_SHA1.java
new file mode 100644
index 0000000..267a9d7
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/dkalgo/P_SHA1.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.dkalgo;
+
+/**
+ *
+ <pre>
+ P_SHA-1 DEFINITION
+ ==================
+ <b>P_SHA-1(secret, seed)</b> =
+ HMAC_SHA-1(secret, A(1) + seed) +
+ HMAC_SHA-1(secret, A(2) + seed) +
+ HMAC_SHA-1(secret, A(3) + seed) + ...
+ <i>Where + indicates concatenation.</i>
+ <br>
+ A() is defined as:
+ A(0) = seed
+ A(i) = HMAC_SHA-1(secret, A(i-1))
+ <br>
+ <i>Source : RFC 2246 - The TLS Protocol Version 1.0
+ Section 5. HMAC and the pseudorandom function</i>
+ </pre>
+ *
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+
+public class P_SHA1
+        implements DerivationAlgorithm {
+
+    private byte[] secret;
+    private String seed;
+
+    public byte[] createKey(byte[] secret, String labelAndNonce, int offset,
+                            long length) throws ConversationException {
+        try {
+            Mac mac = Mac.getInstance("HmacSHA1");
+            
+            byte[] tempBytes = P_hash(secret, labelAndNonce.getBytes(), mac,(offset + (int) length));
+            
+            byte[] key = new byte[(int)length];
+            
+            for(int i = 0; i < key.length; i++)
+            	key[i] = tempBytes[i+offset];
+
+            return key;
+        } catch (Exception ex) {
+            throw new ConversationException("Key Derivation : P_SHA-1: " +
+                    ex.getMessage());
+        }
+    }
+
+    /**
+     * Stolen from WSUsernameToken  :-)
+     *
+     * @param secret
+     * @param seed
+     * @param mac
+     * @param required
+     * @return
+     * @throws java.lang.Exception
+     */
+    private static byte[] P_hash(byte[] secret, byte[] seed, Mac mac,
+                                 int required) throws Exception {
+        byte[] out = new byte[required];
+        int offset = 0, tocpy;
+        byte[] A, tmp;
+        A = seed;
+        while (required > 0) {
+            SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
+            mac.init(key);
+            mac.update(A);
+            A = mac.doFinal();
+            mac.reset();
+            mac.init(key);
+            mac.update(A);
+            mac.update(seed);
+            tmp = mac.doFinal();
+            tocpy = min(required, tmp.length);
+            System.arraycopy(tmp, 0, out, offset, tocpy);
+            offset += tocpy;
+            required -= tocpy;
+        }
+        return out;
+    }
+
+    private static int min(int a, int b) {
+        return (a > b) ? b : a;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/message/info/DerivedKeyInfo.java b/src/org/apache/ws/sandbox/security/conversation/message/info/DerivedKeyInfo.java
new file mode 100644
index 0000000..cb04ea8
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/message/info/DerivedKeyInfo.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.message.info;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.token.DerivedKeyToken;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+
+import java.util.Hashtable;
+
+/**
+ * @author Ruchith
+ * @version 1.0
+ */
+
+public class DerivedKeyInfo {
+
+    private Log log = LogFactory.getLog(DerivedKeyInfo.class.getName());
+
+    private Hashtable properties;
+    private String id;
+    private String algorithm;
+    private int generation;
+    private int offset;
+    private long length;
+    private String label;
+    private String nonce;
+    private int usageCount;
+    private SecurityTokenReference secTokenRef;
+    private SecurityTokenReference secTokRef2DkToken;
+    private DerivedKeyToken dkTok = null;
+
+    public DerivedKeyInfo(DerivedKeyToken dkt) throws WSSecurityException {
+    	this.dkTok=dkt;
+        this.properties = dkt.getProperties();
+        this.generation = dkt.getGeneration();
+        this.offset = dkt.getOffset();
+        this.length = dkt.getLength();
+        this.label = dkt.getLabel();
+        this.nonce = dkt.getNonce();
+        this.id = dkt.getID();
+        this.algorithm = dkt.getAlgorithm();
+        //I need this info in the KeyDerivator
+        //Please feel free to suggest a better method to get the reference info into the KeyDerivator
+        this.secTokenRef = dkt.getSecuityTokenReference();
+        log.debug("DerivedKeyInfo :created. dktId: " + this.id);
+    }
+
+    public int getGeneration() {
+        return generation;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public long getLength() {
+        return length;
+    }
+
+    public String getNonce() {
+        return nonce;
+    }
+
+    public int getOffset() {
+        return offset;
+    }
+
+    public Hashtable getProperties() {
+        return properties;
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
+    public SecurityTokenReference getSecurityTokenReference() {
+        return secTokenRef;
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * @param reference
+     */
+    public void setSecTokRef2DkToken(SecurityTokenReference reference) {
+        secTokRef2DkToken = reference;
+    }
+
+    public SecurityTokenReference getSecTokRef2DkToken() {
+        return secTokRef2DkToken;
+    }
+    /**
+     * @return
+     */
+    public DerivedKeyToken getDkTok() {
+        return dkTok;
+    }
+
+    /**
+     * @param token
+     */
+    public void setDkTok(DerivedKeyToken token) {
+        dkTok = token;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/message/info/SecurityContextInfo.java b/src/org/apache/ws/sandbox/security/conversation/message/info/SecurityContextInfo.java
new file mode 100644
index 0000000..e4916b4
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/message/info/SecurityContextInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.message.info;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken;
+
+/**
+ * @author Kau
+ * @author Ruchith
+ */
+public class SecurityContextInfo {
+
+    private Log log = LogFactory.getLog(SecurityContextInfo.class.getName());
+
+    /**
+     * Shared secret taken from the RequestedProofToken
+     */
+    private byte[] sharedSecret;
+
+    /**
+     * Identifier of the SecurityContextToken
+     */
+    private String identifier;
+
+    /**
+     * The frequency at which the keys are derived
+     * If this frequency is set to 0 then keys are not derived and the shared secret
+     * is used to sign/encrypt messages
+     */
+    private int frequency;
+
+    /**
+     * This element will be useful to store in the hashtable to get
+     * information about the security context
+     *
+     * @param securityContextToken
+     * @param requestedProofToken
+     */
+    public SecurityContextInfo(SecurityContextToken securityContextToken,
+                               RequestedProofToken requestedProofToken,
+                               int frequency) throws WSSecurityException {
+        this.sharedSecret = requestedProofToken.getSharedSecret();
+        this.identifier = securityContextToken.getIdentifier();
+        this.frequency = frequency; // frequency of refreshing the derrived key
+        log.debug("SecurityContextInfo: created. SCT Identifier: " + identifier);
+        /** @todo get the values of other elements (any elements) of SCT*/
+    }
+
+    /**
+     * TEMPORARY METHOD FOR TESTING ONLY TIL I GET THE LATEST PROOF TOKEN
+     * This element will be useful to store in the hashtable to get
+     * information about the security context
+     *
+     * @param securityContextToken
+     * @param requestedProofToken
+     */
+    public SecurityContextInfo(SecurityContextToken securityContextToken,
+                               byte[] sharedSecret,
+                               int frequency) throws WSSecurityException {
+
+        this.sharedSecret = sharedSecret;
+        this.identifier = securityContextToken.getIdentifier();
+        this.frequency = frequency; // frequency of refreshing the derrived key
+        /** @todo get the values of other elements (any elements) of SCT*/
+    }
+    
+    
+	public SecurityContextInfo(String uuid,
+								   byte[] sharedSecret,
+								   int frequency) throws WSSecurityException {
+
+			this.sharedSecret = sharedSecret;
+			this.identifier = uuid;
+			this.frequency = frequency; // frequency of refreshing the derrived key
+			/** @todo get the values of other elements (any elements) of SCT*/
+	}
+     
+    /**
+     * @return
+     */
+    public int getFrequency() {
+        return frequency;
+    }
+
+    /**
+     * @return
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return
+     */
+    public byte[] getSharedSecret() {
+        return sharedSecret;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/message/token/BaseToken.java b/src/org/apache/ws/sandbox/security/conversation/message/token/BaseToken.java
new file mode 100644
index 0000000..9436353
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/message/token/BaseToken.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.message.token;
+
+/**
+ * Class BaseToken
+ */
+public class BaseToken {
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/message/token/DerivedKeyToken.java b/src/org/apache/ws/sandbox/security/conversation/message/token/DerivedKeyToken.java
new file mode 100644
index 0000000..e83fb88
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/message/token/DerivedKeyToken.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.message.token;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.ConversationConstants;
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+import org.apache.ws.sandbox.security.conversation.dkalgo.DerivationAlgorithm;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ <DerivedKeyToken wsu:Id="..." wsc:Algorithm="...">
+ <SecurityTokenReference>...</SecurityTokenReference>
+ <Properties>...</Properties>
+ <Generation>...</Generation>
+ <Offset>...</Offset>
+ <Length>...</Length>
+ <Label>...</Label>
+ <Nonce>...</Nonce>
+ </DerivedKeyToken>
+ */
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+public class DerivedKeyToken {
+
+    private Log log = LogFactory.getLog(DerivedKeyToken.class.getName());
+
+    public static final QName TOKEN = new QName(ConversationConstants.WSC_NS,
+            ConversationConstants.
+            DERIVED_KEY_TOKEN_LN);
+
+    //These are the elements that are used to create the SecurityContextToken
+    protected Element element = null;
+    protected Element elementSecurityTokenReference = null;
+    protected Element elementProperties = null;
+    protected Element elementGeneration = null;
+    protected Element elementOffset = null;
+    protected Element elementLength = null;
+    protected Element elementLabel = null;
+    protected Element elementNonce = null;
+
+    /**
+     * This will create an empty DerivedKeyToken
+     *
+     * @param doc THe DOM document
+     */
+    public DerivedKeyToken(Document doc) {
+        log.debug("DerivedKeyToken: created");
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.
+                DERIVED_KEY_TOKEN_LN);
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+    }
+
+    /**
+     * This will create a DerivedKeyToken object with the given DErivedKeyToken element
+     *
+     * @param elem The DErivedKeyToken DOM element
+     * @throws WSSecurityException If the element is not a derived key token
+     */
+    public DerivedKeyToken(Element elem) throws WSSecurityException {
+        log.debug("DerivedKeyToken: created : element constructor");
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType00", new Object[]{el});
+        }
+        this.elementSecurityTokenReference = (Element) WSSecurityUtil.
+                getDirectChild(this.element,
+                        ConversationConstants.SECURITY_TOKEN_REFERENCE_LN,
+                        WSConstants.WSSE_NS);
+        this.elementProperties = (Element) WSSecurityUtil.getDirectChild(this.
+                element, ConversationConstants.PROPERTIES_LN,
+                ConversationConstants.WSC_NS);
+        this.elementGeneration = (Element) WSSecurityUtil.getDirectChild(this.
+                element, ConversationConstants.GENERATION_LN,
+                ConversationConstants.WSC_NS);
+        this.elementOffset = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.OFFSET_LN, ConversationConstants.WSC_NS);
+        this.elementLength = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.LENGTH_LN, ConversationConstants.WSC_NS);
+        this.elementLabel = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.LABEL_LN, ConversationConstants.WSC_NS);
+        this.elementNonce = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.NONCE_LN, ConversationConstants.WSC_NS);
+    }
+
+    /**
+     * Sets the security token reference of the derived key token
+     * This is the reference to the shared secret used in the conversation/context
+     *
+     * @param doc The DOM document
+     * @param ref Security token reference
+     */
+    public void setSecuityTokenReference(Document doc, SecurityTokenReference ref) {
+        this.elementSecurityTokenReference = ref.getElement();
+        //WSSecurityUtil.appendChildElement(doc, this.element, ref.getElement());
+        this.element.appendChild(ref.getElement());
+    }
+
+    /**
+     * Returns the SecurityTokenReference of the derived key token
+     *
+     * @return
+     * @throws WSSecurityException
+     */
+    public SecurityTokenReference getSecuityTokenReference() throws
+            WSSecurityException {
+        if (this.elementSecurityTokenReference != null) {
+            return new SecurityTokenReference(this.elementSecurityTokenReference);
+        }
+        return null;
+    }
+
+    //Write the getter for security token reference
+
+    /**
+     * This adds a property into
+     * /DerivedKeyToken/Properties
+     *
+     * @param doc       The DOM document
+     * @param propName  Name of the property
+     * @param propValue Value of the property
+     */
+    private void addProperty(Document doc, String propName, String propValue) {
+        if (this.elementProperties == null) { //Create the properties element if it is not there
+            this.elementProperties = doc.createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" +
+                    ConversationConstants.PROPERTIES_LN);
+            WSSecurityUtil.setNamespace(this.elementProperties,
+                    ConversationConstants.WSC_NS,
+                    WSConstants.WSSE_PREFIX);
+            this.element.appendChild(this.elementProperties);
+        }
+        Element tempElement = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + propName);
+        tempElement.appendChild(doc.createTextNode(propValue));
+
+        this.elementProperties.appendChild(tempElement);
+    }
+
+    /**
+     * This is used to set the Name, Label and Nonce element values in the properties element
+     * <b>At this point I'm not sure if these are the only properties that will appear in the
+     * <code>Properties</code> element. There fore this method is provided
+     * If this is not required feel free to remove this :D
+     * </b>
+     *
+     * @param doc   The DOM document
+     * @param name  Value of the Properties/Name element
+     * @param label Value of the Properties/Label element
+     * @param nonce Value of the Properties/Nonce element
+     */
+    public void setProperties(Document doc, String name, String label,
+                              String nonce) {
+        Hashtable table = new Hashtable(3);
+        table.put("Name", name);
+        table.put("Label", label);
+        table.put("Nonce", nonce);
+        this.setProperties(doc, table);
+    }
+
+    /**
+     * If there are other types of properties other than Name, Label and Nonce
+     * This is provided for extensibility purposes
+     *
+     * @param properties The properties and values in a hashtable
+     */
+    public void setProperties(Document doc, Hashtable properties) {
+        Enumeration keys = properties.keys();
+        while (keys.hasMoreElements()) {
+            String propertyName = (String) keys.nextElement(); //Get the property name
+            //Check whether this property is already there
+            //If so change the value
+            Node node = WSSecurityUtil.findElement(this.elementProperties,
+                    propertyName,
+                    ConversationConstants.WSC_NS);
+            if (node != null && node instanceof Element) { //If the node is not null
+                Text node1 = getFirstNode((Element) node);
+                node1.setData((String) properties.get(propertyName));
+            } else {
+                this.addProperty(doc, propertyName,
+                        (String) properties.get(propertyName));
+            }
+        }
+    }
+
+    public Hashtable getProperties() {
+        if (this.elementProperties != null) {
+            Hashtable table = new Hashtable();
+            NodeList nodes = this.elementProperties.getChildNodes();
+            for (int i = 0; i < nodes.getLength(); i++) {
+                Node tempNode = nodes.item(i);
+                if (tempNode instanceof Element) {
+                    Text text = this.getFirstNode((Element) tempNode);
+                    table.put(tempNode.getNodeName(), text.getData());
+                }
+            }
+
+        }
+        return null;
+    }
+
+    /**
+     * Sets the length of the derived key
+     *
+     * @param doc    The DOM document
+     * @param length The length of the derived key as a long
+     */
+    public void setLength(Document doc, long length) {
+        this.elementLength = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.LENGTH_LN);
+        WSSecurityUtil.setNamespace(this.elementLength,
+                ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementLength.appendChild(doc.createTextNode(Long.toString(length)));
+        this.element.appendChild(this.elementLength);
+    }
+
+    public long getLength() {
+        if (this.elementLength != null) {
+            return Long.parseLong(getFirstNode(this.elementLength).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the offset
+     *
+     * @param doc    The DOM document
+     * @param offset The offset value as an integer
+     */
+    public void setOffset(Document doc, int offset) throws ConversationException {
+        //This element MUST NOT be used if the <Generation> element is specified
+        if (this.elementGeneration == null) {
+            this.elementOffset = doc.createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" +
+                    ConversationConstants.OFFSET_LN);
+            WSSecurityUtil.setNamespace(this.elementOffset,
+                    ConversationConstants.WSC_NS,
+                    ConversationConstants.WSC_PREFIX);
+            this.elementOffset.appendChild(doc.createTextNode(Integer.toString(offset)));
+            this.element.appendChild(this.elementOffset);
+        } else {
+            throw new ConversationException("Offset cannot be set along with generation - generation is already set");
+        }
+
+    }
+
+    public int getOffset() {
+        if (this.elementOffset != null) {
+            return Integer.parseInt(getFirstNode(this.elementOffset).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the generation of the derived key
+     *
+     * @param doc        The DOM document
+     * @param generation generation value as an integer
+     */
+    public void setGeneration(Document doc, int generation) throws
+            ConversationException {
+        //This element MUST NOT be used if the <Offset> element is specified
+        if (this.elementOffset == null) {
+            this.elementGeneration = doc.createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" + ConversationConstants.GENERATION_LN);
+            WSSecurityUtil.setNamespace(this.elementGeneration,
+                    ConversationConstants.WSC_NS,
+                    ConversationConstants.WSC_PREFIX);
+            this.elementGeneration.appendChild(doc.createTextNode(Integer.toString(generation)));
+            this.element.appendChild(this.elementGeneration);
+        } else {
+            throw new ConversationException("Generatation cannot be set along with offset - Offset is already set");
+        }
+    }
+
+    public int getGeneration() {
+        if (this.elementGeneration != null) {
+            return Integer.parseInt(getFirstNode(this.elementGeneration).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the label of the derived key
+     *
+     * @param doc   The DOM document
+     * @param label Label value as a string
+     */
+    public void setLabel(Document doc, String label) {
+        this.elementLabel = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.LABEL_LN);
+        WSSecurityUtil.setNamespace(this.elementLabel, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementLabel.appendChild(doc.createTextNode(label));
+        this.element.appendChild(this.elementLabel);
+    }
+
+    /**
+     * Sets the nonce value of the derived key
+     *
+     * @param doc   The DOM document
+     * @param nonce Nonce value as a string
+     */
+    public void setNonce(Document doc, String nonce) {
+        this.elementNonce = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.NONCE_LN);
+        WSSecurityUtil.setNamespace(this.elementNonce, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementNonce.appendChild(doc.createTextNode(nonce));
+        this.element.appendChild(this.elementNonce);
+
+    }
+
+    /**
+     * Returns the label of the derived key token
+     *
+     * @return Label of the derived key token
+     */
+    public String getLabel() {
+        if (this.elementLabel != null) {
+            return getFirstNode(this.elementLabel).getData();
+        }
+        return null;
+    }
+
+    /**
+     * Return the nonce of the derived key token
+     *
+     * @return Nonce of the derived key token
+     */
+    public String getNonce() {
+        if (this.elementNonce != null) {
+            return getFirstNode(this.elementNonce).getData();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the first text node of an element.
+     *
+     * @param e the element to get the node from
+     * @return the first text node or <code>null</code> if node
+     *         is null or is not a text node
+     */
+    private Text getFirstNode(Element e) {
+        Node node = e.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * Returns the dom element of this <code>SecurityContextToken</code> object.
+     *
+     * @return the DerivedKeyToken element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     *
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Gets the id.
+     *
+     * @return the value of the <code>wsu:Id</code> attribute of this
+     *         DerivedKeyToken
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * Set the id of this derived key token.
+     *
+     * @param id the value for the <code>wsu:Id</code> attribute of this
+     *           DerivgedKeyToken
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+    /**
+     * Gets the derivattion algorithm
+     *
+     * @return the value of the <code>wsc:Algorithm</code> attribute of this
+     *         DerivedKeyToken
+     */
+    public String getAlgorithm() {
+        String algo = this.element.getAttributeNS(ConversationConstants.WSC_NS,
+                "Algorithm");
+        if (algo == null || algo.equals("")) {
+            return DerivationAlgorithm.P_SHA_1;
+        } else {
+            return algo;
+        }
+    }
+
+    /**
+     * Set the derivattion algorithm of this derived key token.
+     *
+     * @param derivattion algorithm the value for the <code>wsu:Algorithm</code> attribute of this
+     *                    DerivgedKeyToken
+     */
+    public void setAlgorithm(String algo) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                ConversationConstants.WSC_NS,
+                ConversationConstants.
+                WSC_PREFIX);
+        this.element.setAttributeNS(ConversationConstants.WSC_NS,
+                prefix + ":Algorithm", algo);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/message/token/SecurityContextToken.java b/src/org/apache/ws/sandbox/security/conversation/message/token/SecurityContextToken.java
new file mode 100644
index 0000000..51119ee
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/message/token/SecurityContextToken.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.ConversationConstants;
+import org.apache.ws.sandbox.security.conversation.ConversationUtil;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+public class SecurityContextToken {
+
+    public static final QName TOKEN = new QName(ConversationConstants.WSC_NS,
+            ConversationConstants.
+            SECURITY_CONTEXT_TOKEN_LN);
+
+    /**
+     * Security context token element
+     */
+    protected Element element = null;
+
+    /**
+     * Identifier element
+     */
+    protected Element elementIdentifier = null;
+
+    /**
+     * Constructor to create the SCT
+     *
+     * @param doc
+     */
+    public SecurityContextToken(Document doc) {
+
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+
+        this.elementIdentifier = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.IDENTIFIER_LN);
+
+        this.element.appendChild(this.elementIdentifier);
+
+        String uuid = ConversationUtil.generateUuid(); //Generate a uuid from ConversationUtil
+
+        this.elementIdentifier.appendChild(doc.createTextNode(uuid));
+    }
+
+    /**
+     * Constructor to create the SCT with a given uuid
+     *
+     * @param doc
+     */
+    public SecurityContextToken(Document doc, String uuid) {
+
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+
+        this.elementIdentifier = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.IDENTIFIER_LN);
+
+        this.element.appendChild(this.elementIdentifier);
+
+        this.elementIdentifier.appendChild(doc.createTextNode(uuid));
+    }
+
+    /**
+     * This is used to create a SecurityContestToken using a DOM Element
+     *
+     * @param elem The DOM element: The security context token
+     * @throws WSSecurityException If the element passed in in not a security context token
+     */
+    public SecurityContextToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {    // If the element is not a security context token
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN, "badTokenType00",
+                    new Object[]{el});
+        }
+        this.elementIdentifier = (Element) WSSecurityUtil.getDirectChild(element, ConversationConstants.IDENTIFIER_LN, ConversationConstants.WSC_NS);
+    }
+
+    /**
+     * Set the identifier.
+     *
+     * @param name sets a text node containing the identifier into
+     *             the identifier element.
+     */
+    public void setIdentifier(Document doc, String uuid) {
+        Text node = getFirstNode(this.elementIdentifier);
+        node.setData(uuid);
+    }
+
+    /**
+     * Get the identifier.
+     *
+     * @return the data from the identifier element.
+     */
+    public String getIdentifier() {
+        if (this.elementIdentifier != null) {
+            //System.out.println("In !=null "+ this.elementIdentifier.getFirstChild().toString());
+            return getFirstNode(this.elementIdentifier).getData();
+        }
+        return null;
+    }
+
+    public void setElement(Element elem) {
+        this.element.appendChild(elem);
+    }
+
+    /**
+     * Returns the first text node of an element.
+     *
+     * @param e the element to get the node from
+     * @return the first text node or <code>null</code> if node
+     *         is null or is not a text node
+     */
+    private Text getFirstNode(Element e) {
+        Node node = e.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * Returns the dom element of this <code>SecurityContextToken</code> object.
+     *
+     * @return the <code>wsse:UsernameToken</code> element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     *
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Gets the id.
+     *
+     * @return the value of the <code>wsu:Id</code> attribute of this
+     *         SecurityContextToken
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * Set the id of this security context token.
+     *
+     * @param id the value for the <code>wsu:Id</code> attribute of this
+     *           SecurityContextToken
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/conversation/sessions/SessionMonitor.java b/src/org/apache/ws/sandbox/security/conversation/sessions/SessionMonitor.java
new file mode 100644
index 0000000..a3065e5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/conversation/sessions/SessionMonitor.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.conversation.sessions;
+
+/**
+ * Monitor for the conversation sessions
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.security.conversation.ConversationException;
+import org.apache.ws.sandbox.security.conversation.ConversationSession;
+import org.apache.ws.security.util.Loader;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Vector;
+
+public class SessionMonitor extends Thread {
+
+    private Log log = LogFactory.getLog(SessionMonitor.class.getName());
+
+    /**
+     * Session lifetime in milliseconds
+     */
+    private long sessionLifetime;
+
+    /**
+     * 
+     */
+    private long reapPeriodicity;
+
+    /**
+     *
+     */
+    private Hashtable sessionTable;
+
+    /**
+     *
+     */
+    private Vector expiredSessions = new Vector();
+
+    private long lastReaped = System.currentTimeMillis();
+
+    public SessionMonitor(Hashtable sessionTable)
+            throws ConversationException {
+        //this.setPriority(Thread.MAX_PRIORITY);
+        try {
+            Properties prop = getProperties("SessionMonitor.properties");
+            this.reapPeriodicity =
+                    Long.parseLong(prop.getProperty("org.apache.ws.security.converasation.session.reapPeriodicity"));
+            this.sessionLifetime =
+                    Long.parseLong(prop.getProperty("org.apache.ws.security.converasation.session.sessionLifetime"));
+            log.debug("Reap periodicity from prop file: " + this.reapPeriodicity);
+            log.debug("Session lifetime from prop file: " + this.sessionLifetime);
+        } catch (Exception e) {
+            log.debug("SessionMonitor: Cannot load SessionMonitor.properties using defaults: \n"
+                    + "org.apache.ws.security.converasation.session.reapInterval="
+                    + 60000
+                    + "org.apache.ws.security.converasation.session.sessionLifetime"
+                    + 1800000);
+            this.reapPeriodicity = 60000;
+            this.sessionLifetime = 1800000;
+        }
+        this.sessionTable = sessionTable;
+        log.debug("Session monitor created");
+    }
+
+    /**
+     * STOLEN FROM  org.apache.ws.security.components.crypto.CryptoFactory
+     * Gets the properties for SessionMonitor
+     * The functions loads the property file via
+     * {@link Loader.getResource(String)}, thus the property file
+     * should be accesible via the classpath
+     *
+     * @param propFilename the properties file to load
+     * @return a <code>Properties</code> object loaded from the filename
+     */
+    private Properties getProperties(String propFilename) {
+        Properties properties = new Properties();
+        try {
+            URL url = Loader.getResource(propFilename);
+            properties.load(url.openStream());
+            log.debug("SessionMonitor.properties found");
+        } catch (Exception e) {
+            log.debug("Cannot find SessionMonitor property file: " + propFilename);
+            throw new RuntimeException("SessionMonitor: Cannot load properties: " + propFilename);
+        }
+        return properties;
+    }
+
+    public void run() {
+        while (true) {
+            long now = System.currentTimeMillis();
+            log.debug("Diff: " + (now - (lastReaped + reapPeriodicity)));
+            if (now > (lastReaped + reapPeriodicity)) {
+                log.debug("Special:Ruchith:Waiting to get session");
+                synchronized (this.sessionTable) {
+                    log.debug("Checking sessions");
+                    Enumeration keys = this.sessionTable.keys();
+                    while (keys.hasMoreElements()) {
+                        String tempId = (String) keys.nextElement();
+                        ConversationSession session =
+                                (ConversationSession) this.sessionTable.get(tempId);
+                        synchronized (session) {
+                            log.debug("Session: " + tempId);
+                            if (this.isExpirable(session))
+                                this.expireSession(tempId);
+                        }
+                    }
+                }
+                lastReaped = now;
+            }
+            try {
+                sleep(reapPeriodicity / 2);
+            } catch (InterruptedException e) {
+                log.debug(e.getMessage());
+            }
+
+        }
+
+    }
+
+    private boolean isExpirable(ConversationSession session) {
+        long lastTouched = session.getLastTouched();
+        if ((lastTouched + this.sessionLifetime) < System.currentTimeMillis())
+            return true;
+        else
+            return false;
+    }
+
+    private void expireSession(String identifier) {
+        log.debug("Expirign session " + identifier);
+        this.sessionTable.remove(identifier);
+        this.expiredSessions.add(identifier);
+    }
+
+    public Vector getExpiredSessionIds() {
+        return (Vector) this.expiredSessions.clone();
+    }
+
+    public Hashtable getLiveSessions() {
+        return (Hashtable) this.sessionTable.clone();
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/policy/message/token/AppliesTo.java b/src/org/apache/ws/sandbox/security/policy/message/token/AppliesTo.java
new file mode 100644
index 0000000..ff5c1bc
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/policy/message/token/AppliesTo.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.policy.message.token;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.sandbox.security.trust.message.token.CompositeElement;
+import org.apache.ws.security.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ */
+public class AppliesTo extends CompositeElement {
+	
+	public static final QName TOKEN = new QName(TrustConstants.WSP_NS, TrustConstants.APPLIESTO_LN, TrustConstants.WSP_PREFIX);
+
+	/**
+	 * The WS-Addressing impl is bound to Apache Axis, therefore the 
+	 * org.apache.axis.message.addressing.EndpointReference cannot be used here
+	 * since it will bring Axis specific stuff into the common core of wss4j 
+	 */
+	private Element endpointReferenceElement;
+	private Text addressValueText;
+
+	/**
+	 * Constructor for AppliesTo
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public AppliesTo(Element elem) throws WSTrustException {	
+		super(elem);
+	}
+	
+	/**
+	 * Constructor for AppliesTo
+	 * @param doc
+	 */
+	public AppliesTo(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * Set the value of the <code>wsa:EndpointReference/wsa:Address</code>
+	 * @param eprValue
+	 */
+	public void setEndpointReference(String eprValue) {
+		if(this.endpointReferenceElement != null)  //If there's an existing element remove it and
+			this.element.removeChild(this.endpointReferenceElement);
+		
+		//Create a new element and add it
+		this.endpointReferenceElement = this.element.getOwnerDocument().createElementNS(TrustConstants.WSA_NS, TrustConstants.WSA_PREFIX + ":" + TrustConstants.ENDPOINT_REFERENCE_LN);
+		Element tempAddrElem = this.element.getOwnerDocument().createElementNS(TrustConstants.WSA_NS, TrustConstants.WSA_PREFIX + ":" + TrustConstants.ADDRESS_LN);
+		
+		this.addressValueText = this.element.getOwnerDocument().createTextNode(eprValue);
+		tempAddrElem.appendChild(addressValueText);
+		this.endpointReferenceElement.appendChild(tempAddrElem);
+		this.element.appendChild(endpointReferenceElement);
+		
+	}
+	
+	/**
+	 * Returns the value of the <code>wsa:EndpointReference/wsa:Address</code>
+	 * @return
+	 */
+	public String getAppliesToAddressEpr() {
+		if(this.addressValueText != null)
+			return this.addressValueText.getNodeValue();
+		else 
+			return null;
+	}
+	
+	public void addChildElement(Element elem) {
+		this.element.appendChild(elem);
+	}
+	
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/**
+	 * Populates the attribute elements with given elements
+	 * This method will be called with the child elements of the <code>wsa:AppliesTo</code>
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#deserializeChildElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		if(elem.getNodeName().equals(TrustConstants.WSA_PREFIX + ":" + TrustConstants.ENDPOINT_REFERENCE_LN)) {
+			NodeList list = elem.getChildNodes();
+			for(int i = 0; i < list.getLength(); i++) {
+				Node tempNode = list.item(i);
+				if(tempNode.getNodeType() == Node.ELEMENT_NODE) { //This MUST be the Address Element
+					NodeList tempNodeList = tempNode.getChildNodes();
+					for(int j = 0; j < tempNodeList.getLength(); j++) {
+						if(tempNodeList.item(i).getNodeType() == Node.TEXT_NODE) {//This MUST be the Address value
+							this.addressValueText = (Text)tempNodeList.item(0);
+							this.endpointReferenceElement = elem;
+							break;
+						}
+					}
+				} else {
+					throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+							WSTrustException.DESC_EXPECTED_CHILD_ELEM,
+							new Object[]{ 
+							TrustConstants.WSA_PREFIX, TrustConstants.ADDRESS_LN, 
+							TrustConstants.WSA_PREFIX, TrustConstants.ENDPOINT_REFERENCE_LN});
+				}
+			}
+			
+
+			
+		} else {
+			//If the Passed elemt is not a wsa:EndpointReference element
+			throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+					WSTrustException.DESC_EXPECTED_CHILD_ELEM,
+					new Object[]{ 
+					TrustConstants.WSA_PREFIX, TrustConstants.ENDPOINT_REFERENCE_LN,
+					TOKEN.getPrefix(), TOKEN.getLocalPart()});
+		}
+		
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/RSTRParser.java b/src/org/apache/ws/sandbox/security/trust/RSTRParser.java
new file mode 100644
index 0000000..716d369
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/RSTRParser.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import org.apache.ws.sandbox.security.policy.message.token.AppliesTo;
+import org.apache.ws.sandbox.security.trust.message.token.BinarySecret;
+import org.apache.ws.sandbox.security.trust.message.token.ComputedKey;
+import org.apache.ws.sandbox.security.trust.message.token.Entropy;
+import org.apache.ws.sandbox.security.trust.message.token.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedProofToken;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedSecurityToken;
+import org.apache.ws.sandbox.security.trust2.Lifetime;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.xml.utils.QName;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class' functionality will be included in the RequestSecurityTokenResponse class itself :-)
+ * When a  RequestSecurityTokenResponse instance is created with a corresponding 
+ * DOM Element it will parse that element and populate its properties
+ * 
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ * 
+ * This parses the RequestSecurityTokenResponse. This will be extremely useful for 
+ * requestor classes.
+ * 
+ */
+public class RSTRParser {
+
+    private Element element = null;
+	private AppliesTo appto = null;
+	private Lifetime lifeTime = null;
+	private RequestedSecurityToken reqtedTok = null;
+	private RequestedProofToken proofTok = null;
+	private Entropy entropy = null;
+	private ComputedKey ckey = null;
+	private BinarySecret binSecret = null;
+	
+    private static final QName APPLIES_TO =
+        new QName(TrustConstants.WSP_NS, "AppliesTo");
+    private static final QName LIFE_TIME =
+        new QName(TrustConstants.WST_NS, "Lifetime");
+    private static final QName REQUESTED_ST =
+        new QName(TrustConstants.WST_NS, "RequestedSecurityToken");
+    private static final QName PROOF_TOKEN =
+        new QName(TrustConstants.WST_NS, "RequestedProofToken");
+    private static final QName ENTROPY =
+        new QName(TrustConstants.WST_NS, "Entropy");
+    private static final QName COMPUTED_KEY =
+        new QName(TrustConstants.WST_NS, "ComputedKey");
+    private static final QName BIN_SECRET = 
+		new QName(TrustConstants.WST_NS, "BinarySecret");
+		
+    public void processRSTR(RequestSecurityTokenResponse rstr)
+        throws WSTrustException, WSSecurityException {
+//        element = rstr.getElement();
+//
+//        NodeList list = element.getChildNodes();
+//        int len = list.getLength();
+//        Node nod;
+//        Element elem;
+//        for (int i = 0; i < len; i++) {
+//            nod = list.item(i);
+//            if (nod.getNodeType() != Node.ELEMENT_NODE)
+//                continue;
+//            elem = (Element) nod;
+//
+//            QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
+//
+//            if (el.equals(APPLIES_TO)) {
+//                appto = new AppliesTo(elem);
+//            } else if (el.equals(LIFE_TIME)) {
+//                //TODO: Fix the problem
+//                //lifeTime = new Lifetime(elem);
+//            } else if (el.equals(REQUESTED_ST)) {
+//                reqtedTok = new RequestedSecurityToken(elem);
+//                System.out.println("Found reqtedToken....");
+//            } else if (el.equals(PROOF_TOKEN)) {
+//                proofTok = new RequestedProofToken(elem);
+//                this.handleProofToken();
+//            } else if (el.equals(ENTROPY)) {
+//                entropy = new Entropy(elem);
+//				handleEntropy();
+//            } else {
+//                //TODO :: Do something :-0
+//            }
+//
+//        } //end of for loop
+    }
+
+    private void handleProofToken()
+        throws WSTrustException, WSSecurityException {
+
+        NodeList list = this.proofTok.getElement().getChildNodes();
+
+        int len = list.getLength();
+        Node nod;
+        Element elem;
+        for (int i = 0; i < len; i++) {
+            nod = list.item(i);
+            if (nod.getNodeType() != Node.ELEMENT_NODE)
+                continue;
+            elem = (Element) nod;
+
+            QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
+
+            if (el.equals(COMPUTED_KEY)) {
+                ckey = new ComputedKey(elem);
+                //TODO: proofTok.s
+                Node val = elem.getChildNodes().item(0);
+                if (val.getNodeType() == Node.TEXT_NODE) {
+                    ckey.setValue(val.getNodeValue());
+                } else {
+                    throw new WSTrustException("Parser Exception");
+                }
+            } else if (el.equals(BinarySecret.TOKEN)) {
+				this.binSecret = new BinarySecret(elem);
+				Node val = elem.getChildNodes().item(0);
+				if (val.getNodeType() == Node.TEXT_NODE) {
+					binSecret.setValue(val.getNodeValue());
+				} else {
+				throw new WSTrustException("Parser Exception");
+				}
+                
+            }else{
+//				TODO :: Do something :-0
+            }
+
+        } //for
+
+    } //handleProof
+
+    private void handleEntropy() throws WSTrustException, WSSecurityException{
+    	
+//        NodeList list = this.entropy.getElement().getChildNodes();
+//
+//        int len = list.getLength();
+//        Node nod;
+//        Element elem;
+//        for (int i = 0; i < len; i++) {
+//            nod = list.item(i);
+//            if (nod.getNodeType() != Node.ELEMENT_NODE)
+//                continue;
+//            elem = (Element) nod;
+//
+//            QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
+//
+//            if (el.equals(BinarySecret.TOKEN)) {
+//                this.binSecret = new BinarySecret(elem);
+//                entropy.setBinarySecret(binSecret);
+//                Node val = elem.getChildNodes().item(0);
+//                if (val.getNodeType() == Node.TEXT_NODE) {
+//                    binSecret.setBinarySecretValue(val.getNodeValue());
+//                } else {
+//                    throw new WSTrustException("Parser Exception");
+//                }
+//            } else {
+//                //TODO :: Do something :-0
+//            }
+//
+//        } //for
+
+    } //handleEntropy
+    
+
+    /**
+     * @return
+     */
+    public AppliesTo getAppto() {
+        return appto;
+    }
+
+    /**
+     * @return
+     */
+    public BinarySecret getBinSecret() {
+        return binSecret;
+    }
+
+    /**
+     * @return
+     */
+    public ComputedKey getCkey() {
+        return ckey;
+    }
+
+    /**
+     * @return
+     */
+    public Entropy getEntropy() {
+        return entropy;
+    }
+
+    /**
+     * @return
+     */
+    public Lifetime getLifeTime() {
+        return lifeTime;
+    }
+
+    /**
+     * @return
+     */
+    public RequestedProofToken getProofTok() {
+        return proofTok;
+    }
+
+    /**
+     * @return
+     */
+    public RequestedSecurityToken getReqtedTok() {
+        return reqtedTok;
+    }
+
+    
+    /**
+     * @param to
+     */
+    public void setAppto(AppliesTo to) {
+        appto = to;
+    }
+
+    /**
+     * @param secret
+     */
+    public void setBinSecret(BinarySecret secret) {
+        binSecret = secret;
+    }
+
+    /**
+     * @param key
+     */
+    public void setCkey(ComputedKey key) {
+        ckey = key;
+    }
+
+    /**
+     * @param entropy
+     */
+    public void setEntropy(Entropy entropy) {
+        this.entropy = entropy;
+    }
+
+    /**
+     * @param lifetime
+     */
+    public void setLifeTime(Lifetime lifetime) {
+        lifeTime = lifetime;
+    }
+
+    /**
+     * @param token
+     */
+    public void setProofTok(RequestedProofToken token) {
+        proofTok = token;
+    }
+
+    /**
+     * @param token
+     */
+    public void setReqtedTok(RequestedSecurityToken token) {
+        reqtedTok = token;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/RequestResolver.java b/src/org/apache/ws/sandbox/security/trust/RequestResolver.java
new file mode 100644
index 0000000..f317a59
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/RequestResolver.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.message.Info.RequestInfo;
+import org.apache.ws.sandbox.security.trust.message.token.RequestType;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Malinda Kaushalye
+ *         To be completed later
+ */
+public class RequestResolver {
+    static Log log = LogFactory.getLog(STSManager.class.getName());
+    Document doc;
+    RequestInfo reqInfo = new RequestInfo();
+
+    /**
+     * 
+     */
+    public RequestResolver(Document doc) {
+        this.doc = doc;
+    }
+
+    public RequestInfo resolve() throws WSSecurityException {
+    	
+        //get the request type and base
+        Element elemRequestType = (Element) WSSecurityUtil.findElement(doc, RequestType.TOKEN.getLocalPart(), RequestType.TOKEN.getNamespaceURI());
+
+        //set request type    
+        if (elemRequestType != null) {
+            log.debug("Resolving request type");
+            RequestType requestType;
+			try {
+				requestType = new RequestType(elemRequestType);
+				String temp = requestType.getValue();
+	            this.reqInfo.setRequestType(requestType.getValue());
+			} catch (WSTrustException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+
+            log.debug("Resolving request type complete");
+        }
+        
+        return this.reqInfo;
+
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/STSManager.java b/src/org/apache/ws/sandbox/security/trust/STSManager.java
new file mode 100644
index 0000000..c82b491
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/STSManager.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.Loader;
+import org.apache.ws.sandbox.security.trust.issue.STIssuer;
+import org.apache.ws.sandbox.security.trust.message.Info.RequestInfo;
+import org.apache.ws.sandbox.security.trust.renew.STRenewer;
+import org.apache.ws.sandbox.security.trust.validate.STValidator;
+import org.w3c.dom.Document;
+
+import java.util.Hashtable;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         <p/>
+ *         The main objective of <code>STSManager</code> is to work as a
+ *         decision making component in the server side.
+ *         It decides to whom this request must be handed over,
+ *         and to carry out the task it uses one <code>RequestResolver</code>
+ *         and one <code>RequestInfo</code>  object. This analogous to the real
+ *         world the Manager, Clerk and the Report scenario,
+ *         where (STS)Manager orders clerk(<code>RequestResolver</code> )
+ *         to resolve a certain request and handover a
+ *         report (<code>RequestInfo</code> ) about the request.
+ *         Depending on the RequestInfo <code>STSManager</code>
+ *         decides the worker class. The worker class can be
+ *         an Issuer, Validator or a Renewer. Each STS must
+ *         define its Issuer, Validator and Renewer class names
+ *         in the server-config.wsdd file. <code>STSServerHandler</code>  will
+ *         read it and give to the <code>STSManager</code> as a hash table.
+ *         <code>STSManager</code> will load the appropriate worker class and give the
+ *         response and request documents for further processing.
+ */
+public class STSManager {
+    static Log log = LogFactory.getLog(STSManager.class.getName());
+    //Following worker classes are defined in the server-config.wsdd
+    String issuerClassName = null;
+    String renewerClassName = null;
+    String validatorClassName = null;
+    //To keep the class name of the worker (issuer, renewer or validater)
+    String requestType = "";
+    String tokenType = "";
+    Hashtable hashOps;
+
+    /**
+     * @param hashOps set of parameters coming from STSServerHandler.
+     */
+    public STSManager(Hashtable hashOps) {
+        this.hashOps = hashOps;
+    }
+
+    /**
+     * Handle the request and build the Response Envelope
+     * <p/>
+     * <p/>
+     * <p/>
+     * Handle the request and build the Response Envelope
+     *
+     * @param req request message envelop as a DOM Document
+     * @param res response message envelop as a DOM Document
+     * @return modified response message envelop as a DOM Document
+     *         Note :
+     *         (may not need to use since response message envelop is passed as a reference)
+     */
+    public Document handleRequest(Document req, Document res)
+            throws WSTrustException {
+
+        RequestResolver requestResolver = new RequestResolver(req);
+
+        try {
+            log.debug("STS Manager resolving the request");
+            RequestInfo requestInfo = requestResolver.resolve();
+            this.requestType = requestInfo.getRequestType();            
+            //this.tokenType = requestInfo.getTokenType();//we may need to have <wsp:Applies> to override the <wst:TokenType>
+            log.debug("STS Manager resolving completed");
+        } catch (WSSecurityException wsEx) {
+
+            //wsEx.printStackTrace();
+            throw new WSTrustException("STSManager: cannot resolve the request: ",
+                    wsEx);
+        }
+        /********************************************************************
+         * Issue
+         */
+        if (this.requestType.equals(TrustConstants.ISSUE_SECURITY_TOKEN)) {
+            //issue    
+            
+            //get the woker class name
+            
+            this.issuerClassName = (String) hashOps.get(TrustConstants.ISSUER_CLASS);
+            log.debug("Issuer class" + this.issuerClassName);
+            //Create the instance of the issue/renew/validate class  
+            Class wClass = null;
+            try {
+                wClass = Loader.loadClass(issuerClassName);
+            } catch (ClassNotFoundException e) {
+                throw new WSTrustException("STSManager: cannot load security token class: ",
+                        e);
+            }
+            STIssuer stissuer = null;
+            try {
+                //Create a new instance of the STIssuer
+                stissuer = (STIssuer) wClass.newInstance();
+
+            } catch (java.lang.Exception e) {
+                throw new WSTrustException("STSManager: cannot create instance of security token issuer: "
+                        + stissuer,
+                        e);
+            }
+
+            try {
+                res = stissuer.issue(req, res);
+
+            } catch (java.lang.Exception e) {
+                System.out.println(e.getMessage());
+                throw new WSTrustException("STSManager: could not issue a token " + stissuer,
+                        e);
+                        
+            }
+
+            /********************************************************************
+             * Renew
+             */
+        } else if (this.requestType.equals(TrustConstants.RENEW_SECURITY_TOKEN)) { //renew    
+            //                    get the woker class name
+            this.renewerClassName = (String) hashOps.get(TrustConstants.RENEWER_CLASS);
+            log.debug("renewer  class" + this.renewerClassName);
+            //Create the instance of the issue/renew/validate class  
+            Class wClass = null;
+            try {
+                wClass = Loader.loadClass(renewerClassName);
+            } catch (ClassNotFoundException e) {
+                throw new WSTrustException("STSManager: cannot load security token class: ",
+                        e);
+            }
+            STRenewer stRenewer = null;
+            try {
+                //Create a new instance of the STIssuer
+                stRenewer = (STRenewer) wClass.newInstance();
+
+            } catch (java.lang.Exception e) {
+                throw new WSTrustException("STSManager: cannot create instance of security token renewer: "
+                        + stRenewer,
+                        e);
+            }
+
+            try {
+                res = stRenewer.renew(req, res);
+
+            } catch (java.lang.Exception e) {
+                throw new WSTrustException("STSManager: could not renew the token " + stRenewer,
+                        e);
+            }
+            /********************************************************************
+             * validate
+             */
+        } else if (
+                this.requestType.equals(TrustConstants.VALIDATE_SECURITY_TOKEN)) { //validate    
+//                    get the woker class name
+            this.validatorClassName = (String) hashOps.get(TrustConstants.VALIDATOR_CLASS);
+            log.debug("validatorClassName " + this.validatorClassName);
+            //Create the instance of the issue/renew/validate class  
+            Class wClass = null;
+            try {
+                wClass = Loader.loadClass(validatorClassName);
+            } catch (ClassNotFoundException e) {
+                throw new WSTrustException("STSManager: cannot load security token class: ",
+                        e);
+            }
+            STValidator stValidator = null;
+            try {
+                //Create a new instance of the STIssuer
+                stValidator = (STValidator) wClass.newInstance();
+
+            } catch (java.lang.Exception e) {
+                throw new WSTrustException("STSManager: cannot create instance of security token validator: "
+                        + stValidator,
+                        e);
+            }
+            try {
+
+                res = stValidator.validate(req, res);
+
+            } catch (java.lang.Exception e) {
+                throw new WSTrustException("STSManager: could not validate the token " + stValidator,
+                        e);
+            }
+        } else {
+            throw new WSTrustException("STSManager: Cannot Identify the Request Type ");
+
+        }
+        return res;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/STSUtil.java b/src/org/apache/ws/sandbox/security/trust/STSUtil.java
new file mode 100644
index 0000000..d786ead
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/STSUtil.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.axis.message.MessageElement;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.sandbox.security.trust.message.token.BaseToken;
+import org.apache.ws.security.util.Loader;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * @author Malinda Kaushalye
+ *
+ * STSUtil is the place where all the utility functions are stored.
+ * These utility functions are being used in various modules.
+ * 
+ */
+public class STSUtil {
+
+	
+
+	
+	/**
+	   * Returns an array of Message Elements for given array of elements 
+	   * 
+	   * @param elem
+	   * @return
+	   */
+	  public static MessageElement[] generateMessgaeElemArray(Element[] elem){
+		MessageElement[] meArr=new MessageElement[elem.length];
+		for (int i=0;i<elem.length;i++){
+			meArr[i]=new MessageElement(elem[i]);
+		}
+		return meArr;
+	  }
+	 
+	  /**
+	   * Returns a MessageElement for a given Element
+	   * 
+	   * @param elem 
+	   * @return
+	   */
+	  public static MessageElement generateMessgaeElement(Element elem){
+		MessageElement me=new MessageElement(elem);	
+		return me;
+	  }
+
+	
+
+	  /**
+	   * Currently  support only for direct references
+	   * @param doc
+	   * @return
+	   */
+	  public static BinarySecurity findBinarySecurityToken(Document doc){
+		try {
+			BinarySecurity binarySecurity;
+			//first find base token
+			Element elemBase=(Element)WSSecurityUtil.findElement(doc,BaseToken.TOKEN.getLocalPart(),BaseToken.TOKEN.getNamespaceURI());
+			Element elemBaseChild=(Element)elemBase.getFirstChild();
+			//If the first child is null then return
+			if((elemBaseChild==null)){
+				return null;
+			}
+			//If the first child is a binary token
+					
+			if((elemBaseChild.getLocalName().equals("BinarySecurityToken"))   ){
+				binarySecurity=new BinarySecurity(elemBaseChild);
+				return binarySecurity;
+			}else if((elemBaseChild.getLocalName().equals(SecurityTokenReference.SECURITY_TOKEN_REFERENCE) )  ){
+				return null;
+			}else{
+			    return null;
+			}
+		} catch (WSSecurityException e) {			
+			e.printStackTrace();
+		}		
+		return null;
+	  }
+	
+	 /**
+	 * Currently we do support only for direct references
+	 * @param doc
+	 * @return
+	 */
+	public static UsernameToken findUsernameToken(Document doc){
+	  try {
+		UsernameToken unt;
+		  //first find base token
+		  Element elemBase=(Element)WSSecurityUtil.findElement(doc,BaseToken.TOKEN.getLocalPart(),BaseToken.TOKEN.getNamespaceURI());
+		  Element elemBaseChild=(Element)elemBase.getFirstChild();
+		  //If the first child is null then return
+		  if((elemBaseChild==null)){
+			  return null;
+		  }
+		 //If the first child is a UNT
+					
+		  if((elemBaseChild.getLocalName().equals("UsernameToken"))   ){
+			  unt=new UsernameToken(elemBaseChild);
+			  return unt;
+		  }else{
+			  return null;
+		  }
+	  } catch (WSSecurityException e) {
+			
+		  e.printStackTrace();
+	  }		
+	  return null;
+	}
+
+/**
+ * Replaces the Security Token Reference element with its Referenced element
+ * Reason : In the Trust Comminicator no header elements are visible
+ * @param doc start element of the search (Usually the wst:Base element)
+ * @throws WSSecurityException
+ */
+	  public static void replaceSecurityTokenReferences(Document doc)throws WSSecurityException{
+		//WSSecurityUtil.findElement(doc,SecurityTokenReference.TOKEN.getLocalPart(),SecurityTokenReference.TOKEN.getNamespaceURI());
+		NodeList nList=doc.getElementsByTagName(SecurityTokenReference.SECURITY_TOKEN_REFERENCE);
+		for(int i=0; i<nList.getLength();i++){
+			SecurityTokenReference secTokRef=(SecurityTokenReference)nList.item(i);//SecTokRef
+			Reference ref=secTokRef.getReference();
+			String uri=ref.getURI();		
+			//System.out.println("uri"+uri);
+			Element elemFound=WSSecurityUtil.getElementByWsuId(doc,uri);
+			doc.replaceChild(secTokRef.getElement(),elemFound);			
+		}			
+			  	
+	  }
+	/**
+	 * Load properties 
+	 * @param propFilename
+	 * @return
+	 */
+	public  static Properties getProperties(String propFilename) {
+		Properties properties = new Properties();
+		try {
+			URL url = Loader.getResource(propFilename);
+			properties.load(url.openStream());
+			
+		} catch (Exception e) {
+			
+		}
+		return properties;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/TrustConstants.java b/src/org/apache/ws/sandbox/security/trust/TrustConstants.java
new file mode 100644
index 0000000..e082884
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/TrustConstants.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ * @version 1.0
+ *          <p/>
+ *          TrustConstants is the class where all the constants of the WS-Trust implementation are kept.
+ *          Primarily all the namespaces, prefixes and local names of the tokens are kept here.
+ *          Then all the codes used in message exchanges are also listed here.
+ *          all the configuration parameters are also kept here.
+ */
+
+public class TrustConstants {
+
+    private static final String NS_YEAR_PREFIX = "http://schemas.xmlsoap.org/ws/2005/02/";
+    public static final String WST_NS = NS_YEAR_PREFIX + "trust";
+    public static final String WST_PREFIX = "wst";
+
+    //WS-Policy related constants
+    public static final String WSP_NS = "http://schemas.xmlsoap.org/ws/2004/09/policy";
+    public static final String WSP_PREFIX = "wsp";	
+    public static final String APPLIESTO_LN = "AppliesTo";
+    
+    //WS-Addressing related constants
+    public static final String WSA_NS = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
+    public static final String WSA_PREFIX = "wsa";
+    public static final String ENDPOINT_REFERENCE_LN = "EndpointReference";
+    public static final String ADDRESS_LN = "Address";
+	
+    //Utility related constants
+    public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+    public static final String WSU_PREFIX = "wsu";
+    public static final String CREATED_LN = "Created";
+    public static final String EXPIRES_LN = "Expires";
+    public static final String ID_ATTR = "Id";
+    
+    //local names of the token used in WS-Trust
+    public static final String TOKEN_TYPE_LN = "TokenType";
+    public static final String REQUEST_TYPE_LN = "RequestType";
+    public static final String KEY_TYPE_LN = "KeyType";
+    public static final String KEY_SIZE_LN = "KeySize";
+    public static final String LIFE_TIME_LN = "Lifetime";
+    public static final String BASE_LN = "Base";
+    public static final String STATUS_LN = "Status";
+    public static final String CODE_LN = "Code";
+    public static final String REASON_LN = "Reason";
+    public static final String RENEWING_LN = "Renewing";
+    public static final String RENEW_TARGET_LN = "RenewTarget";
+    public static final String CANCEL_TARGET_LN = "CancelTarget";
+    public static final String REQUESTED_TOKEN_CANCELLED_LN = "RequestedTokenCancelled";
+    public static final String ALLOWPOSTDATING_LN = "AllowPostdating";
+    public static final String BINARY_SECRET_LN= "BinarySecret";
+    public static final String ENTROPY_LN= "Entropy";
+    public static final String CLAIMS_LN = "Claims";
+    public static final String COMPUTED_KEY_LN = "ComputedKey";
+    
+    public static final String REQUEST_SECURITY_TOKEN_LN = "RequestSecurityToken";
+    public static final String REQUEST_SECURITY_TOKEN_RESPONSE_LN = "RequestSecurityTokenResponse";
+    public static final String REQUESTED_SECURITY_TOKEN_LN = "RequestedSecurityToken";
+    public static final String REQUESTED_PROOF_TOKEN_LN = "RequestedProofToken";
+
+    //Attributes
+    public static final String CONTEXT_ATTR = "Context";
+    public static final String BINARY_SECRET_TYPE_ATTR = "Type";
+    public static final String CLAIMS_DIALECT_ATTR = "Dialect";
+    public static final String RENEWING_ALLOW_ATTR = "Allow";
+    public static final String RENEWING_OK_ATTR = "OK";
+    
+    // The request type is specified using following URIs as specified in the WS-Trust specification
+    public static final String ISSUE_SECURITY_TOKEN = WST_NS + "/Issue";
+    public static final String RENEW_SECURITY_TOKEN = WST_NS + "/Renew";
+    public static final String VALIDATE_SECURITY_TOKEN = WST_NS + "/Validate";
+    public static final String CANCEL_SECURITY_TOKEN = WST_NS + "/Cancel";
+
+    //RSTRs
+    public static final String RSTR_PREFIX = WST_NS + "/RSTR";
+    public static final String ISSUE_SECURITY_TOKEN_RSTR = RSTR_PREFIX + "/Issue";
+    public static final String RENEW_SECURITY_TOKEN_RSTR = RSTR_PREFIX + "/Renew";
+    public static final String VALIDATE_SECURITY_TOKEN_RSTR = RSTR_PREFIX + "/Validate";
+    public static final String CANCEL_SECURITY_TOKEN_RSTR = RSTR_PREFIX + "/Cancel";
+
+    //RSTs
+    public static final String RST_PREFIX = WST_NS + "/RST";
+    public static final String ISSUE_SECURITY_TOKEN_RST = RST_PREFIX + "/Issue";
+    public static final String RENEW_SECURITY_TOKEN_RST = RST_PREFIX + "/Renew";
+    public static final String VALIDATE_SECURITY_TOKEN_RST = RST_PREFIX + "/Validate";
+    public static final String CANCEL_SECURITY_TOKEN_RST = RST_PREFIX + "/Cancel";
+    
+    //STATUS
+    public static final String STATUS_PREFIX = WST_NS + "/status";
+    public static final String STATUS_VALID = STATUS_PREFIX + "/valid";
+    public static final String STATUS_INVALID = STATUS_PREFIX + "/invalid";
+
+    //Token yypes
+    public static final String TOKEN_TYPE_RSTR_STATUS = RSTR_PREFIX + "/Status";
+    
+    //Binary secret types
+    public static final String BINARY_SECRET_ASYMMETRIC_KEY = WST_NS + "/AsymmetricKey";
+	public static final String BINARY_SECRET_SYMMETRIC_KEY = WST_NS + "/SymmetricKey";
+	public static final String BINARY_SECRET_NONCE_VAL= WST_NS + "/Nonce";
+    
+    //COmputedKey types
+    public static final String COMPUTED_KEY_PSHA1 = WST_NS + "/CK/PSHA1"; 
+  
+    //For STS there should be an issuer class specified in the STS.properties
+    public static final String ISSUER_CLASS = "org.apache.ws.axis.security.trust.service.SecurityTokenService.issuerClass";
+    //For STS there should be a renewer class specified in the STS.properties
+    public static final String RENEWER_CLASS = "org.apache.ws.axis.security.trust.service.SecurityTokenService.renewerClass";
+    //For STS there should be a validator class specified in the STS.properties
+    public static final String VALIDATOR_CLASS = "org.apache.ws.axis.security.trust.service.SecurityTokenService.validatorClass";
+
+    //In the request, The token type can be specified in the client-config
+    public static final String TOKEN_TYPE = "TokenType";
+    //The request type , issue/renew or validate 
+    public static final String REQUEST_TYPE = "RequestType";
+
+    //for BASED_ON_X509
+    public static final String BASE_CERT_FILE = "BaseCertFile";
+    public static final String USER = "user";//alias of the certificate
+
+    //for BASED_ON_USERNAME_TOKEN
+    public static final String UNT_USER = "UNTUser";
+    public static final String UNT_PWCALLBACK_CLASS = "passwordCallbackClass";
+
+    //requester class
+    public static final String REQUESTER_CLASS = "requesterClass";
+}
+
diff --git a/src/org/apache/ws/sandbox/security/trust/TrustEngine.java b/src/org/apache/ws/sandbox/security/trust/TrustEngine.java
new file mode 100644
index 0000000..8f486c5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/TrustEngine.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.security.trust.verify.STVerifier;
+import org.apache.ws.security.util.Loader;
+import org.w3c.dom.Document;
+
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * @author Ruchith
+ *         This is used in at the web service end to verfy trust of request
+ *         Three verifiers are used in verifying trust which represents the three key stpes performed by the STS
+ *         These three verifier classes and their properties can be specified in the trustEngine.properties file
+ *         The verifier classes will accept a Property object having the properties from the specified property file
+ *         The author of the verifier classes can decide how to carryout the verfication when the verify() is called
+ */
+public class TrustEngine {
+
+    private Log log = LogFactory.getLog(TrustEngine.class.getName());
+
+    /**
+     * Verifier class used to verify claims
+     */
+    private final String CLAIM_VERIFIER_CLASS = "org.apache.ws.security.trust.ClaimVerifierClass";
+
+    /**
+     * Verifier class used to verify signatures
+     */
+    private final String SIGNATURE_VERIFIER_CLASS = "org.apache.ws.security.trust.SignatureVerifierClass";
+
+    /**
+     * Verifier class used to verify the issuer
+     */
+    private final String ISSUER_VERIFIER_CLASS = "org.apache.ws.security.trust.IssuerVerifierClass";
+
+    /**
+     * Properties for the claims verifier
+     */
+    private final String CLAIM_VERIFIER_PROPERTIES = "org.apache.ws.security.trust.ClaimVerifierProperties";
+
+    /**
+     * Properties for the signature verifier
+     */
+    private final String SIGNATURE_VERIFIER_PROPERTIES = "org.apache.ws.security.trust.SignatureVerifierProperties";
+
+    /**
+     * Properties for the issuer verifier
+     */
+    private final String ISSUER_VERIFIER_PROPERTIES = "org.apache.ws.security.trust.IssuerVerifierProperties";
+
+    /**
+     * Claim verifier
+     */
+    private STVerifier claimVerifier;
+
+    /**
+     * Signature verifier
+     */
+    private STVerifier signatureVerifier;
+
+    /**
+     * Issuer verifier
+     */
+    private STVerifier issuerVerifier;
+
+    /**
+     * Create a trust engine with config info in a Properties file
+     *
+     * @param propFileName Property file name
+     * @throws WSTrustException
+     */
+    public TrustEngine(String propFileName) throws WSTrustException {
+//        try {
+//            Properties prop = getProperties(propFileName);
+//            this.configureEngine(prop);
+//        } catch (Exception e) {
+//            throw new WSTrustException(e.getMessage(),e);
+//        }        
+    }
+
+    /**
+     * Create a trust engine with the default properties file
+     * The default properties file used is trustEngine.properties
+     *
+     * @throws WSTrustException
+     */
+    public TrustEngine() throws WSTrustException {
+        try {
+            Properties prop = getProperties("trustEngine.properties");
+            this.configureEngine(prop);
+        } catch (Exception e) {
+            throw new WSTrustException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Configure the trust engine
+     * This is called from the constructor
+     *
+     * @param prop Config details for the TrustEngine
+     * @throws WSTrustException
+     */
+    private void configureEngine(Properties prop) throws WSTrustException {
+        Properties climProp, sigProp, issuerProp;
+        climProp = getProperties(prop.getProperty(CLAIM_VERIFIER_PROPERTIES));
+        sigProp = getProperties(prop.getProperty(SIGNATURE_VERIFIER_PROPERTIES));
+        issuerProp = getProperties(prop.getProperty(ISSUER_VERIFIER_PROPERTIES));
+
+        this.claimVerifier = loadClass(prop.getProperty(CLAIM_VERIFIER_CLASS), climProp);
+        this.signatureVerifier = loadClass(prop.getProperty(SIGNATURE_VERIFIER_CLASS), sigProp);
+        this.issuerVerifier = loadClass(prop.getProperty(ISSUER_VERIFIER_CLASS), issuerProp);
+    }
+
+    /**
+     * Verify trust for a given request
+     *
+     * @param doc The request message
+     * @return If all three verifiers verifies this will return true
+     * @throws WSTrustException
+     */
+    public boolean verifyTrust(Document doc) throws WSTrustException {
+        if (this.claimVerifier.verify(doc) && this.signatureVerifier.verify(doc) && this.issuerVerifier.verify(doc))
+            return true;
+        else
+            return false;
+    }
+
+    /**
+     * STOLEN FROM  org.apache.ws.security.components.crypto.CryptoFactory :-)
+     * Gets the properties for SessionMonitor
+     * The functions loads the property file via
+     * {@link Loader.getResource(String)}, thus the property file
+     * should be accesible via the classpath
+     *
+     * @param propFilename the properties file to load
+     * @return a <code>Properties</code> object loaded from the filename
+     */
+    private Properties getProperties(String propFilename) {
+        Properties properties = new Properties();
+        try {
+            URL url = Loader.getResource(propFilename);
+            properties.load(url.openStream());
+            log.debug("SessionMonitor.properties found");
+        } catch (Exception e) {
+            log.debug("Cannot find SessionMonitor property file: " + propFilename);
+            throw new RuntimeException("SessionMonitor: Cannot load properties: " + propFilename);
+        }
+        return properties;
+    }
+
+    /**
+     * Load the verifier class with the given properties
+     *
+     * @param className  Name of the Verifier class
+     * @param properties Properties of the
+     * @return
+     * @throws WSTrustException
+     */
+    private STVerifier loadClass(String className, Properties properties) throws WSTrustException {
+        STVerifier verifier = null;
+        Class verfierClass = null;
+        try {
+            verfierClass = Loader.loadClass(className);
+            Class[] classes = new Class[]{Properties.class};
+            Constructor c = verfierClass.getConstructor(classes);
+            verifier = (STVerifier) c.newInstance(new Object[]{properties});
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(className + " Not Found");
+        } catch (Exception e) {
+            throw new WSTrustException(e.getMessage(), e);
+        }
+        return verifier;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/WSTrustException.java b/src/org/apache/ws/sandbox/security/trust/WSTrustException.java
new file mode 100644
index 0000000..d54178f
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/WSTrustException.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust;
+
+import java.rmi.RemoteException;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         Exception class for WS-Trust implementation.
+ */
+public class WSTrustException extends RemoteException {	
+	
+	public static final String INVALID_REQUEST = "InvalidRequest";
+    
+	
+	public static final String DESC_INCORRECT_CHILD_ELEM = "incorrectChildElement";
+	public static final String DESC_EXPECTED_CHILD_ELEM = "expectedChildElement";
+	public static final String DESC_CHILD_IN_VALUE_ELEM = "childInValueElement";
+	public static final String DESC_TEXT_IN_COMPOSITE_ELEM = "textInCompositeElement";
+    
+    private static ResourceBundle resources;
+
+    private String faultCode;
+    private String faultString;
+    
+    static {
+        try {
+            resources = ResourceBundle.getBundle("org.apache.ws.security.trust.errors");
+        } catch (MissingResourceException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    /**
+     * 
+     * @param faultCode
+     * @param msgId
+     * @param args
+     * @param exception
+     */
+    public WSTrustException(String faultCode, String msgId, Object[] args, Throwable exception) {
+        super(getMessage(faultCode, null, null),exception);
+        this.faultCode = faultCode;
+        this.faultString = resources.getString(faultCode);
+    }
+
+    /**
+     * 
+     * @param faultCode
+     * @param msgId
+     * @param args
+     */
+    public WSTrustException(String faultCode, String msgId, Object[] args) {
+        super(getMessage(faultCode, null, null));
+        this.faultCode = faultCode;
+        this.faultString = resources.getString(faultCode);
+    }
+    
+    /**
+     * This can be used to set a custom message in the exception
+     * @param faultCode
+     * @param msg
+     */
+    public WSTrustException(String faultCode, String msg) {
+    	super(msg);
+    	this.faultCode = faultCode;
+    	this.faultString = resources.getString(faultCode);
+    }
+
+    /**
+     * 
+     * @param faultCode
+     * @param msgId
+     * @param args
+     * @return
+     */
+    private static String getMessage(String faultCode, String msgId, Object[] args) {
+        String msg = null;
+        try {
+            msg = resources.getString(faultCode);
+            if (msgId != null) {
+                return msg += (" (" + MessageFormat.format(resources.getString(msgId), args) + ")");
+            }
+        } catch (MissingResourceException e) {
+            throw new RuntimeException("Undefined '" + msgId + "' resource property");
+        }
+        return msg;
+    }
+
+    /**
+     * 
+     * @param message
+     */
+    public WSTrustException(String message) {
+    	super(message);    	
+    }
+    
+    /**
+     * 
+     * @param message
+     * @param ex
+     */
+    public WSTrustException(String message, Throwable ex) {
+    	super(message,ex);    	
+    }
+    
+    
+    /**
+     * Return the fault code
+     * @return
+     */
+	public String getFaultCode() {
+		return TrustConstants.WST_PREFIX + faultCode;
+	}
+	
+	/**
+	 * Return the fault string
+	 * @return
+	 */
+	public String getFaultString() {
+		return faultString;
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/errors.properties b/src/org/apache/ws/sandbox/security/trust/errors.properties
new file mode 100644
index 0000000..296b068
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/errors.properties
@@ -0,0 +1,18 @@
+##Fault codes and fault strings according to the WS-Trust spec
+InvalidRequest = The request was invalid or malformed
+FailedAuthentication = Authentication failed
+RequestFailed = The specified request failed
+InvalidSecurityToken = Security token has been revoked
+AuthenticationBadElements = Insufficient Digest Elements
+BadRequest = The specified RequestSecurityToken is not understood
+ExpiredData = The request data is out of date
+InvaildTimeRange = The requested time range is invaild or unsupported
+InvaildScope = The request scope is invaild or unsupported
+RenewNeeded = A renewable security token has expired
+UnableToRenew = The requested renewal failed
+
+#Other additional fault information can be listed here
+incorrectChildElement={\"{0}\"}\"{1}\" element cannot contain a {\"{3}\"}\"{4}\" element
+expectedChildElement={\"{0}\"}\"{1}\" is expected within the {\"{3}\"}\"{4}\" element
+childInValueElement={\"{0}\"}\"{1}\" element cannot contain any child elements. Found  {\"{3}\"}\"{4}\" 
+textInCompositeElement={\"{0}\"}\"{1}\" composite element cannot contain a value. Found \"{3}\"
diff --git a/src/org/apache/ws/sandbox/security/trust/issue/STIssuer.java b/src/org/apache/ws/sandbox/security/trust/issue/STIssuer.java
new file mode 100644
index 0000000..f349a0d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/issue/STIssuer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.issue;
+
+import org.w3c.dom.Document;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         Builds the response message to issue a token.
+ *         any class that implements <code>STIssuer</code> would have the freedom to
+ *         define its own way of issuing (i.e constructing the response) tokens
+ */
+public interface STIssuer {
+    public Document issue(Document req, Document res) throws Exception;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/issue/X509ToSCTIssuer.java b/src/org/apache/ws/sandbox/security/trust/issue/X509ToSCTIssuer.java
new file mode 100644
index 0000000..7b8dd18
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/issue/X509ToSCTIssuer.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.issue;
+
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.sandbox.security.trust.STSUtil;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.sandbox.security.trust.message.token.BaseToken;
+import org.apache.ws.sandbox.security.trust.message.token.Lifetime;
+import org.apache.ws.sandbox.security.trust.message.token.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust.message.token.RequestType;
+import org.apache.ws.sandbox.security.trust.message.token.RequestedSecurityToken;
+import org.apache.ws.sandbox.security.trust.message.token.TokenType;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+/**
+ * @author Malinda Kaushalye
+ *
+ * Issue SCTs based on X509 certificates.
+ * Developers have to override the method getSecuritContextToken()
+ * @see org.apache.ws.sandbox.security.trust.STIssuer#issue(org.w3c.dom.Document, org.w3c.dom.Document)
+ */
+public abstract class X509ToSCTIssuer implements STIssuer {
+	X509Security x509;
+	int lifeTime = 2*60;//default in minutes
+	Crypto crypto;
+	protected String alias="";
+	
+	/**
+	 * 
+	 */
+	public X509ToSCTIssuer() {
+		super();
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.STIssuer#issue(org.w3c.dom.Document, org.w3c.dom.Document)
+	 */
+	public Document issue(Document req, Document res) throws Exception {
+	
+		
+		Element elemTokenType=(Element)WSSecurityUtil.findElement(req,TokenType.TOKEN.getLocalPart(),TokenType.TOKEN.getNamespaceURI());
+		TokenType tokenType=new TokenType(elemTokenType);
+		
+		Element elemRequestType=(Element)WSSecurityUtil.findElement(req,RequestType.TOKEN.getLocalPart(),RequestType.TOKEN.getNamespaceURI());
+		RequestType requestType=new RequestType(elemRequestType);
+		
+		Element elemBase=(Element)WSSecurityUtil.findElement(req,BaseToken.TOKEN.getLocalPart(),BaseToken.TOKEN.getNamespaceURI());
+		BaseToken base=new BaseToken(elemBase);		
+		
+		BinarySecurity binarySecurity=STSUtil.findBinarySecurityToken(req);
+		//x509=new X509Security(binarySecurity.getElement());
+		Element sct=this.getSecuritContextToken(res,x509);		
+		
+		/////////////////////////////////////////////////////////////////////////////
+		//Now we build the response
+		RequestSecurityTokenResponse requestSecurityTokenResponse=new RequestSecurityTokenResponse(res);
+		
+		RequestedSecurityToken requestedSecurityToken=new RequestedSecurityToken(res);
+		//Token Type
+		TokenType tokenTypeRes=new TokenType(res);
+		tokenTypeRes.setValue(tokenType.getValue());
+		//Request Type
+		RequestType requestTypeRes=new RequestType(res);
+		requestTypeRes.setValue(requestType.getValue());
+
+		//It is RECOMMENDED that the issuer return this element with issued tokens so the 
+		//requestor knows the actual validity period without having to parse the
+		//returned token.
+		Lifetime lt=new Lifetime(res,this.getLifeTime());
+//		Element elemLifeTime = lt.getElement();
+//
+//		//append to req'ed token				
+////		requestedSecurityToken.addToken(tokenTypeRes.getElement());
+////		requestedSecurityToken.addToken(requestTypeRes.getElement());
+//		requestedSecurityToken.addToken(sct);
+//		
+//
+//		RequestedProofToken requestedProofToken=new RequestedProofToken(res);
+//		if(!this.alias.equals("")){
+//			requestedProofToken.build(res, this.crypto, this.alias, requestedProofToken.getElement());
+//		}		
+//		
+//	//	append to response
+//		requestSecurityTokenResponse.addToken(tokenTypeRes.getElement());
+//		requestSecurityTokenResponse.addToken(requestTypeRes.getElement());
+//		requestSecurityTokenResponse.addToken(elemLifeTime);	
+//			
+//		requestSecurityTokenResponse.addToken(requestedSecurityToken.getElement());
+//		requestSecurityTokenResponse.addToken(requestedProofToken.getElement());
+//		requestSecurityTokenResponse.setContext(TrustConstants.ISSUE_SECURITY_TOKEN);
+//		
+//		
+		
+		//append to the body
+		Element elemEnv=res.getDocumentElement();
+		SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(elemEnv);
+		Element elemBody=WSSecurityUtil.findBodyElement(elemEnv.getOwnerDocument(),soapConstants);	
+		
+		//Option1: Use the exisiting response element
+		//Element cld1=(Element)elemBody.getFirstChild().appendChild(requestedSecurityToken.getElement());
+
+
+		//Option2:remove old and create new response element 
+		Element cld0=(Element)elemBody.removeChild((Element)elemBody.getFirstChild());
+		//Element cld1=(Element)elemBody.appendChild(requestSecurityTokenResponse.getElement());
+		
+		
+		return res;
+	}
+	/**
+	 * Override this method to generate the SCT. 
+	 * Application developers can verify the requester
+	 * according to their own mechanism (e.g. Searching a database) 
+	 * The whole request is handed over to the end user to make the process more flexible.
+	 */
+	public abstract Element getSecuritContextToken(Document doc,X509Security x509Sec)throws WSTrustException;
+
+	/**
+	 * @return  Duration in minutes
+	 */
+	public int getLifeTime() {
+		return lifeTime;
+	}
+
+	/**
+	 * @return
+	 */
+	public X509Security getX509() {
+		return x509;
+	}
+
+	/**
+	 * 
+	 * @param time Duration in minutes
+	 */
+	public void setLifeTime(int time) {
+		lifeTime = time;
+	}
+
+	/**
+	 * @return
+	 */
+	public Crypto getCrypto() {
+		return crypto;
+	}
+
+	/**
+	 * @param crypto
+	 */
+	public void setCrypto(Crypto crypto) {
+		this.crypto = crypto;
+	}
+
+	/**
+	 * @return
+	 */
+	public String getAlias() {
+		return alias;
+	}
+
+	/**
+	 * @param string
+	 */
+	public void setAlias(String string) {
+		alias = string;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/Info/RequestInfo.java b/src/org/apache/ws/sandbox/security/trust/message/Info/RequestInfo.java
new file mode 100644
index 0000000..b901fd1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/Info/RequestInfo.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.Info;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+
+/**
+ * @author Malinda Kaushalye
+ *         Act as a Data Object
+ *         Usefull to exchange the information about a request.
+ *         Need more attributes...
+ */
+public class RequestInfo {
+
+    private String requestType;
+    private String tokenType;
+    private String baseType;
+    private String appliesTo;
+
+    public static final String ISSUE = TrustConstants.ISSUE_SECURITY_TOKEN;
+    public static final String RENEW = TrustConstants.RENEW_SECURITY_TOKEN;
+    public static final String VALIDATE = TrustConstants.VALIDATE_SECURITY_TOKEN;
+
+    public static final String X509 = "X509Certificate";
+    public static final String USERNAME = "UsernameToken";
+    public static final String SAML = "SAML";
+    public static final String CUSTOM = "CustomToken";
+
+    /**
+     * 
+     */
+    public RequestInfo() {
+
+    }
+
+    /**
+     * Constructor for RequestInfo
+     *
+     * @param requestType
+     * @param tokenType
+     * @param baseType
+     * @param appliesTo
+     */
+    public RequestInfo(String requestType, String tokenType, String baseType, String appliesTo) {
+        this(requestType, tokenType, baseType);
+        this.appliesTo = appliesTo;
+    }
+
+    /**
+     * Constructor for RequestInfo
+     *
+     * @param requestType
+     * @param tokenType
+     * @param baseType
+     */
+    public RequestInfo(String requestType, String tokenType, String baseType) {
+        this(requestType, tokenType);
+        this.baseType = baseType;
+    }
+
+    /**
+     * Constructor for RequestInfo
+     *
+     * @param requestType
+     * @param tokenType
+     */
+    public RequestInfo(String requestType, String tokenType) {
+        this(requestType);
+        this.tokenType = tokenType;
+    }
+
+    /**
+     * Constructor for RequestInfo
+     *
+     * @param requestType
+     */
+    public RequestInfo(String requestType) {
+        this.requestType = requestType;
+    }
+
+    /**
+     * get RequestType
+     *
+     * @return
+     */
+    public String getRequestType() {
+        return requestType;
+    }
+
+    /**
+     * get TokenType
+     *
+     * @return
+     */
+    public String getTokenType() {
+        return tokenType;
+    }
+
+    /**
+     * set RequestType
+     *
+     * @param string
+     */
+    public void setRequestType(String string) {
+        this.requestType = string;
+    }
+
+    /**
+     * set TokenType
+     *
+     * @param string
+     */
+    public void setTokenType(String string) {
+        tokenType = string;
+    }
+
+    /**
+     * get BaseType
+     *
+     * @return
+     */
+    public String getBaseType() {
+        return baseType;
+    }
+
+    /**
+     * set BaseType
+     *
+     * @param string
+     */
+    public void setBaseType(String string) {
+        baseType = string;
+    }
+
+    /**
+     * get AppliesTo
+     *
+     * @return
+     */
+    public String getAppliesTo() {
+        return appliesTo;
+    }
+
+    /**
+     * set AppliesTo
+     *
+     * @param string
+     */
+    public void setAppliesTo(String string) {
+        appliesTo = string;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/AbstractToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/AbstractToken.java
new file mode 100644
index 0000000..6895d96
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/AbstractToken.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public abstract class AbstractToken {
+
+	/**
+	 * This metod is used to provide the QName of the element to the 
+	 * constructors by the extending types
+	 * @return
+	 */
+	protected abstract QName getToken();
+	
+	protected Element element;
+	protected Document document;
+	
+	/**
+	 * Create a new token with the given document
+	 * @param doc
+	 */
+	public AbstractToken(Document doc) {
+		QName token = this.getToken();
+		this.element = doc.createElementNS(token.getNamespaceURI(), TrustConstants.WST_PREFIX + ":" + token.getLocalPart());
+		this.document = doc;
+	}
+
+	/**
+	 * Tihs constructor accepts a DOM Element instance
+	 * Will populate the internal properties
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public AbstractToken(Element elem) throws WSTrustException {
+		QName token = this.getToken();
+        QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+        if (!el.equals(token))
+            throw new WSTrustException(WSTrustException.INVALID_REQUEST, "badTokenType", new Object[]{el});
+        
+        this.element = elem;
+        this.document = elem.getOwnerDocument();
+        this.parse(this.element);
+
+	}
+
+	/**
+	 * Parses the immediate children of the current token and calls the
+	 * deserializeChildElement method or deserializeElementText
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public void parse(Element elem) throws WSTrustException {
+		NodeList nodeList = elem.getChildNodes();
+		
+		for(int i = 0; i < nodeList.getLength(); i++) {
+			Node tempNode = nodeList.item(i);
+			switch(tempNode.getNodeType()) {
+				case Node.ELEMENT_NODE:
+					this.deserializeChildElement((Element)tempNode);
+					break;
+				/*
+				 * If we don't check for the Text node of a Token like this 
+				 * we'll have to run through the children of this dom 
+				 * element once again in the constructor of each of the tokens
+				 */
+				case Node.TEXT_NODE :
+					this.setElementTextValue((Text)tempNode);
+					break;
+			}
+		}
+	}
+
+	/**
+	 * This is called for each of the  immediate 
+	 * child elements of type <code>Node.ELEMENT_NODE</code> of this token 
+	 * @param elem The child element
+	 * @throws WSSecurityException
+	 */
+	protected abstract void deserializeChildElement(Element elem) throws WSTrustException;
+
+	/**
+	 * This is called with a <code>Text</code> node of the
+	 * current element
+	 * @param textNode
+	 */
+	protected abstract void setElementTextValue(Text textNode) throws WSTrustException;
+	
+	
+    /**
+     * Returns this element
+     * @return 
+     */
+    protected Element getElement() {
+        return element;
+    }
+
+    /**
+     * Sets this element
+     * @param element 
+     */
+    protected void setElement(Element element) {
+        this.element = element;
+    }
+		
+    /**
+     * To display the token
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+	
+    
+    protected void addChild(AbstractToken token) {
+    	this.element.appendChild(token.getElement());
+    }
+    
+    protected void removeChild(AbstractToken token) {
+    	this.element.removeChild(token.getElement());
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/AllowPostdating.java b/src/org/apache/ws/sandbox/security/trust/message/token/AllowPostdating.java
new file mode 100644
index 0000000..d414744
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/AllowPostdating.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author Malinda Kaushalye 
+ * @author Ruchith Fernando
+ * 
+ * AllowPostdating element <p/>This element indicates
+ * that returned tokens should allow requests for postdated tokens.
+ */
+public class AllowPostdating extends AbstractToken {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.ALLOWPOSTDATING_LN, TrustConstants.WST_PREFIX);
+
+    /**
+     * Constructor for AllowPostdating
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public AllowPostdating(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for AllowPostdating
+     *
+     * @param doc
+     */
+    public AllowPostdating(Document doc) {
+        super(doc);
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElementText(org.w3c.dom.Text)
+	 */
+	protected void setElementTextValue(Text textNode) throws WSTrustException{
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+				"There cannot be a value in this element");
+	}
+
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+		"There cannot be a value in this element");
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/BaseToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/BaseToken.java
new file mode 100644
index 0000000..8ff934d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/BaseToken.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         Base token.
+ */
+public class BaseToken {
+    
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.BASE_LN, TrustConstants.WST_PREFIX);
+    Element element;
+
+    /**
+     * Constructor for Base
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public BaseToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                        this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType:base",
+                    new Object[]{el});
+        }
+
+    }
+
+    /**
+     * Constructor for Base
+     *
+     * @param doc
+     */
+    public BaseToken(Document doc) {
+        this.element =
+                doc.createElementNS(TOKEN.getNamespaceURI(),
+                        TOKEN.getPrefix() + ":" + TOKEN.getLocalPart());
+        WSSecurityUtil.setNamespace(this.element,
+                TOKEN.getNamespaceURI(),
+                TrustConstants.WST_PREFIX);
+        this.element.appendChild(doc.createTextNode(""));
+    }
+
+    /**
+     * Return the binary security token of the base token if any
+     *
+     * @return
+     * @throws WSSecurityException
+     */
+    public BinarySecurity getBinarySecurityToken() throws WSSecurityException {
+        BinarySecurity binarySecToken;
+
+        binarySecToken = null;
+        String firstChild = this.element.getFirstChild().getLocalName();
+
+        if ("BinarySecurityToken" == firstChild) {
+
+            binarySecToken =
+                    new BinarySecurity((Element) this.element.getFirstChild());
+            return binarySecToken;
+        } else if ("SecurityTokenReference" == firstChild) {
+
+            SecurityTokenReference secTokRef =
+                    new SecurityTokenReference((Element) this.element.getFirstChild());
+            binarySecToken =
+                    new BinarySecurity(secTokRef.getTokenElement(element.getOwnerDocument(),
+                                    null));
+            return binarySecToken;
+        } else {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType");
+        }
+
+    }
+
+    /**
+     * Currently support only direct reference
+     *
+     * @param binarySecurity
+     * @param asReference
+     */
+    public void setBinarySecurityToken(BinarySecurity binarySecurity) {
+        Element elem = getFirstElement();
+        if (elem != null) {
+            this.element.replaceChild(binarySecurity.getElement(), elem);
+        } else {
+            this.element.appendChild(binarySecurity.getElement());
+        }
+    }
+
+    /**
+     * get the first child element.
+     *
+     * @return the first <code>Element</code> child node
+     */
+    public Element getFirstElement() {
+        for (Node currentChild = this.element.getFirstChild();
+             currentChild != null;
+             currentChild = currentChild.getNextSibling()) {
+            if (currentChild instanceof Element) {
+                return (Element) currentChild;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * @param element
+     */
+    public void setElement(Element element) {
+        this.element = element;
+    }
+
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Other tokens can be added through this method
+     *
+     * @param childToken
+     */
+    public void addToken(Element childToken) {
+        this.element.appendChild(childToken);
+    }
+
+    /**
+     * Tokens can be removed through this method
+     *
+     * @param childToken
+     */
+    public void removeToken(Element childToken) {
+        this.element.removeChild(childToken);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/BinarySecret.java b/src/org/apache/ws/sandbox/security/trust/message/token/BinarySecret.java
new file mode 100644
index 0000000..b6f7cae
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/BinarySecret.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ *
+ * @author Dimuthu Leelarathne.(muthulee@yahoo.com)
+ * @author Ruchith Fernando
+ */
+public class BinarySecret extends ValueElement {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.BINARY_SECRET_LN, TrustConstants.WST_PREFIX);
+    
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param wssConfig
+     * @param elem
+     */
+    public BinarySecret(Element elem) throws WSTrustException {
+    	super(elem);
+    } 
+					
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param wssConfig
+     * @param doc
+     */
+    public BinarySecret(Document doc) {
+    	super(doc);
+    }
+
+    /**
+     * set the Type.
+     * Set one of the three types.
+     * @param ref
+     */
+    public void setTypeAttribute(String type) {
+    	this.element.setAttribute(TrustConstants.BINARY_SECRET_TYPE_ATTR, type);
+    }
+
+    /**
+     * Returns the type attribute value
+     * @return
+     */
+    public String getTypeAttribute() {
+    	return this.element.getAttribute(TrustConstants.BINARY_SECRET_TYPE_ATTR);
+    }
+    
+	/**
+	 * This is provided as an extensibility mechnism to as any attrbute 
+	 * @param attribute
+	 * @param value
+	 */
+	public void addAttribute(String attribute, String value) {
+		this.element.setAttribute(attribute, value);
+	}    
+    
+	/**
+	 * This is to be used to retrieve the value of the 
+	 * custom attrbutes added
+	 * @param attribute
+	 * @return
+	 */
+	public String getAttributeValue(String attribute) {
+		return this.element.getAttribute(attribute);		
+	}
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/CancelRequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/CancelRequestSecurityToken.java
new file mode 100644
index 0000000..9457431
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/CancelRequestSecurityToken.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the class to be used to enerate a RequestSecurityToken for the 
+ * RST cancel binding
+ * 
+ * The additional child elements required for a cancel request is provided here
+ * 
+ * @see org.apache.ws.sandbox.security.trust.TrustConstants#CANCEL_SECURITY_TOKEN
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class CancelRequestSecurityToken extends RequestSecurityToken {
+
+	private CancelTarget cancelTargetElement;
+	
+	/**
+	 * Creates a new <code>wst:RequestSecurityToken</code> element
+	 * setting the given element as the cancel target
+	 * @param doc
+	 * @param targetElement
+	 */
+	public CancelRequestSecurityToken(Document doc, Element targetElement) {
+		super(doc, TrustConstants.CANCEL_SECURITY_TOKEN);
+		this.cancelTargetElement = new CancelTarget(this.document,targetElement);
+		this.addChild(this.cancelTargetElement);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public CancelRequestSecurityToken(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/**
+	 * Sets the given element as the cancel target
+	 * @param targetToken
+	 */
+	public void setCancelTarget(Element targetToken) {
+		if(this.cancelTargetElement == null) {
+			this.cancelTargetElement = new CancelTarget(this.document,targetToken);
+			this.addChild(this.cancelTargetElement);
+		}
+		this.cancelTargetElement.setCancelTarget(targetToken);
+	}
+	
+	/**
+	 * Sets the given security token reference as the cancel target
+	 * NOTE: This method is not necessary but for the completeness sake this was included
+	 * This is because the DOM element of the SecurityTokenReference element
+	 * can be set as the cancel target, But this will be useful if something is to be 
+	 * changed with the SecurityTokenReference
+	 * @param securityTokenReference
+	 */
+	public void setCancelTarget(SecurityTokenReference securityTokenReference) {
+		if(this.cancelTargetElement == null) {
+			this.cancelTargetElement = new CancelTarget(this.document,securityTokenReference);
+			this.addChild(this.cancelTargetElement);
+		}
+		this.cancelTargetElement.setCancelTarget(securityTokenReference);
+	}
+
+	/**
+	 * Handle the serialization of child elements specific to this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.RequestSecurityToken#handleSpecificChildren(org.w3c.dom.Element)
+	 */
+	protected void handleSpecificChildren(Element elem) throws WSTrustException {
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+		if(el.equals(CancelTarget.TOKEN)) {
+			this.cancelTargetElement = new CancelTarget(elem);
+		} else {
+        	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+        			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+					new Object[] {
+        			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+					el.getNamespaceURI(),el.getLocalPart()});
+		}
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/CancelTarget.java b/src/org/apache/ws/sandbox/security/trust/message/token/CancelTarget.java
new file mode 100644
index 0000000..4b4d234
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/CancelTarget.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * The <code>wst:CancelTarget</code> element
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class CancelTarget extends CompositeElement {
+
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.CANCEL_TARGET_LN, TrustConstants.WST_PREFIX);
+	
+    private Element targetToken;
+    private SecurityTokenReference securityTokenReference;
+    
+	/**
+	 * @param doc
+	 */
+	public CancelTarget(Document doc, SecurityTokenReference securityTokenReference) {
+		super(doc);
+		this.securityTokenReference = securityTokenReference;
+		this.element.appendChild(this.securityTokenReference.getElement());
+	}
+	
+	/**
+	 * @param doc
+	 */
+	public CancelTarget(Document doc, Element targetToken) {
+		super(doc);
+		this.targetToken = targetToken;
+		this.element.appendChild(this.targetToken);
+	}
+	
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public CancelTarget(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+
+	/**
+	 * Sets a token as the token to be cancelled
+	 * @param targetToken
+	 */
+	public void setCancelTarget(Element targetToken) {
+		if(this.securityTokenReference != null)
+			this.element.removeChild(this.securityTokenReference.getElement());
+		if(this.targetToken != null)
+			this.element.removeChild(this.targetToken);
+		
+		this.targetToken = targetToken;
+		this.element.appendChild(this.targetToken);
+	}
+	
+	/**
+	 * Sets the given security token reference as the cancel target
+	 * @param securityTokenReference
+	 */
+	public void setCancelTarget(SecurityTokenReference securityTokenReference) {
+		if(this.securityTokenReference != null)
+			this.element.removeChild(this.securityTokenReference.getElement());
+		if(this.targetToken != null)
+			this.element.removeChild(this.targetToken);
+		
+		this.securityTokenReference = securityTokenReference;
+		this.element.appendChild(this.securityTokenReference.getElement());
+	}
+	
+	/**
+	 * Returns the security token reference to the token to be cancelled
+	 * @return
+	 */
+	public SecurityTokenReference getSecurityTokenReference() {
+		return securityTokenReference;
+	}
+	
+	/**
+	 * Returns the target token to be cancelled
+	 * @return
+	 */
+	public Element getTargetToken() {
+		return targetToken;
+	}
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+		if(el.equals(new QName(WSConstants.WSSE_NS,SecurityTokenReference.SECURITY_TOKEN_REFERENCE)) && this.targetToken == null) {
+			try {
+				this.securityTokenReference = new SecurityTokenReference(elem);
+			} catch (WSSecurityException wsse) {
+				throw new WSTrustException(wsse.getMessage(),wsse);
+			}
+		} else if(this.securityTokenReference == null) {
+			this.targetToken = elem;
+		}
+		
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Claims.java b/src/org/apache/ws/sandbox/security/trust/message/token/Claims.java
new file mode 100644
index 0000000..36ff0f5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Claims.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * <code>wst:Claims</code> token
+ * Example token
+ * <pre>
+  <Claims>
+      <SubjectName MatchType="...">...</SubjectName>
+      <X509Extension OID="..." Critical="..." MatchType="...">
+        ...
+      </X509Extension>
+  </Claims>
+  </pre> 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class Claims extends CompositeElement {
+	
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.CLAIMS_LN, TrustConstants.WST_PREFIX);
+
+		
+	public Claims(Document doc) {
+		super(doc);
+	}
+	
+	public Claims(Element elem) throws WSTrustException {
+        super(elem);	
+	}
+	
+	/**
+	 * Set the value of the wst:Claims/@Dialect
+	 * @param value
+	 */
+	public void setDialectAttribute(String value) {
+//		Will worry about null/removing attribute values later
+//		if(value == null) {
+//			if(this.element.getAttribute(TrustConstants.CLAIMS_DIALECT_ATTR) == null)
+//				this.element.removeAttribute(TrustConstants.CLAIMS_DIALECT_ATTR);
+//		}
+		this.element.setAttribute(TrustConstants.CLAIMS_DIALECT_ATTR, value);
+		
+	}
+	
+	/**
+	 * Returns the value of the <code>Dialect</code> attribute
+	 * @return
+	 */
+	public String getDialectAttribute() {
+		return this.element.getAttribute(TrustConstants.CLAIMS_DIALECT_ATTR);
+	}
+	
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) {
+		/*
+		 * We don't have to do anything since the elemets that
+		 * are given in here are custom elements and they can
+		 * be retrieved using getTokenByTagNameNS method
+		 */
+	}
+	
+	/**
+	 * This is provided as an extensibility mechanism to add any
+	 * child element to the <code>wst:Claims</code> element
+	 * @param childToken
+	 */
+	public void addToken(Element childToken) {
+		this.element.appendChild(childToken);
+	}
+	
+	/**
+	 * Adds a list of nodes as children of this 
+	 * <code>wst:Claims</code> element
+	 * @param claimsList A <code>NodeList</code> of the elements
+	 */
+	public void addClaims(NodeList claimsList) {
+		for (int i = 0; i < claimsList.getLength(); i++) {
+			this.element.appendChild(claimsList.item(i));
+		}
+	}
+	
+	
+	/**
+	 * This is provided to be used to extract custom elements from the 
+	 * <code>wst:Claims</code>
+	 * @param namespace
+	 * @param tagName
+	 * @return
+	 */
+	public NodeList getTokensByTagNameNS(String namespace, String tagName) {
+		return this.element.getElementsByTagNameNS(namespace, tagName);
+	}
+	
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Code.java b/src/org/apache/ws/sandbox/security/trust/message/token/Code.java
new file mode 100644
index 0000000..ee2224d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Code.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Malinda
+ * @author Ruchith Fernando
+ *         Code token
+ * @see org.apache.ws.sandbox.security.trust.message.token.Status
+ */
+public class Code extends ValueElement {
+
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.CODE_LN, TrustConstants.WST_PREFIX);
+
+    /**
+     * Constructor for Code
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public Code(Element elem) throws WSTrustException {
+        super(elem);
+    }
+
+    /**
+     * Constructor for Code
+     *
+     * @param doc
+     */
+    public Code(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Constructor for Code
+     *
+     * @param doc
+     * @param value Text to be inserted to Code
+     */
+    public Code(Document doc, String value) {
+    	super(doc);
+    	this.valueText = doc.createTextNode(value);
+        this.element.appendChild(this.valueText);
+    }
+    
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/CompositeElement.java b/src/org/apache/ws/sandbox/security/trust/message/token/CompositeElement.java
new file mode 100644
index 0000000..4d20154
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/CompositeElement.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public abstract class CompositeElement extends AbstractToken {
+
+	/**
+	 * @param doc
+	 */
+	public CompositeElement(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSTrustException
+	 */
+	public CompositeElement(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#setElementTextValue(org.w3c.dom.Text)
+	 */
+	protected void setElementTextValue(Text textNode) throws WSTrustException {
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+				WSTrustException.DESC_TEXT_IN_COMPOSITE_ELEM,
+				new Object[]{this.getToken().getNamespaceURI(),
+				this.getToken().getLocalPart(),
+				textNode.getNodeValue()});
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/ComputedKey.java b/src/org/apache/ws/sandbox/security/trust/message/token/ComputedKey.java
new file mode 100644
index 0000000..b4be160
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/ComputedKey.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ * @author Ruchith Fernando
+ */
+public class ComputedKey extends ValueElement {
+	
+	 public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.COMPUTED_KEY_LN, TrustConstants.WST_PREFIX);
+   	 
+	 /**
+	  * Constructor.
+	  * <p/>
+	  *
+	  * @param wssConfig
+	  * @param elem
+	  */
+	 public ComputedKey(Element elem) throws WSTrustException {
+	 	super(elem);
+	 }
+
+	 /**
+	  * Constructor. <p/>
+	  * 
+	  * @param wssConfig
+	  * @param doc
+	  */
+	 public ComputedKey(Document doc) {
+		 super(doc);
+	 }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Created.java b/src/org/apache/ws/sandbox/security/trust/message/token/Created.java
new file mode 100644
index 0000000..dbac691
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Created.java
@@ -0,0 +1,55 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class Created extends ValueElement {
+
+	public static final QName TOKEN = new QName(TrustConstants.WSU_NS, TrustConstants.CREATED_LN, TrustConstants.WSU_PREFIX);
+	
+	/**
+	 * @param doc
+	 */
+	public Created(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSTrustException
+	 */
+	public Created(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Entropy.java b/src/org/apache/ws/sandbox/security/trust/message/token/Entropy.java
new file mode 100644
index 0000000..5f9a745
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Entropy.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * 
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ * @author Ruchith Fernando
+ */
+public class Entropy extends CompositeElement {
+	private static Log log = LogFactory.getLog(Entropy.class.getName());
+
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.ENTROPY_LN, TrustConstants.WST_PREFIX);
+
+	private BinarySecret binarySecretElement;
+	
+	/**
+	 * Constructor.
+	 * <p/>
+	 *
+	 * @param wssConfig
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public Entropy(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+
+	/**
+	 * Create a new <code>wst:Entropy</code> element
+	 * 
+	 * @param doc
+	 */
+	public Entropy(Document doc) {
+		super(doc);
+	}
+
+
+	/**
+	 * TODO: IMPORTANT : This method should be removed
+	 * set the BinarySecret.
+	 * <p/>
+	 *
+	 * @param secret
+	 */
+	public void setBinarySecret(BinarySecret secret) {
+		this.binarySecretElement = secret;
+	}
+
+	/**
+	 * Sets the binary secret value
+	 * @param type The type uri of the binary secret as a <code>String</code>
+	 * @param secretValue The binary secret value as a <code>String</code>
+	 */
+	public void setBinarySecret(String type, String secretValue) {
+		if(this.binarySecretElement == null) {
+			this.binarySecretElement = new BinarySecret(this.document);
+			this.addChild(this.binarySecretElement);
+		}
+		
+		this.binarySecretElement.setTypeAttribute(type);
+		this.binarySecretElement.setValue(secretValue);
+	}
+	
+	/**
+	 * 
+	 * @return
+	 * @throws WSTrustException
+	 */
+	public BinarySecret getBinarySecret() throws WSTrustException {
+		return this.binarySecretElement;
+	}
+	
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+        QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+        
+        if(el.equals(BinarySecret.TOKEN)) {
+        	this.binarySecretElement = new BinarySecret(elem);
+        } else {
+        	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+        			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+					new Object[] {
+        			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+					el.getNamespaceURI(),el.getLocalPart()});
+        }
+		
+	}
+
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Expires.java b/src/org/apache/ws/sandbox/security/trust/message/token/Expires.java
new file mode 100644
index 0000000..9935ac2
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Expires.java
@@ -0,0 +1,55 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class Expires extends ValueElement {
+
+	public static final QName TOKEN = new QName(TrustConstants.WSU_NS, TrustConstants.EXPIRES_LN, TrustConstants.WSU_PREFIX);
+	
+	/**
+	 * @param doc
+	 */
+	public Expires(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSTrustException
+	 */
+	public Expires(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/IssueRequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/IssueRequestSecurityToken.java
new file mode 100644
index 0000000..9fe3b5a
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/IssueRequestSecurityToken.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.policy.message.token.AppliesTo;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * This is the class to be used to enerate a RequestSecurityToken for the 
+ * RST issuance binding
+ * Some additional child elements are provided for the convenience of the 
+ * developer to carry out an issue request
+ * @see org.apache.ws.sandbox.security.trust.TrustConstants#ISSUE_SECURITY_TOKEN
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class IssueRequestSecurityToken extends RequestSecurityToken {
+	
+    private AppliesTo appliesToElement;
+    private Claims claimsElement;
+    private Entropy entropyElement;
+    private Lifetime lifetimeElement;
+
+    private KeySize keySizeElement;
+    
+    private Renewing renewingElement;
+    	
+	/**
+	 * @param doc
+	 * @param requestType
+	 */
+	public IssueRequestSecurityToken(Document doc) {
+		super(doc, TrustConstants.ISSUE_SECURITY_TOKEN);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public IssueRequestSecurityToken(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/**
+	 * Sets the <code>wst:AppliesTo</code> value of the <code>wst:RequestSecurityToken</code>
+	 * @param appliesTo The <code>wst:AppliesTo/wsa:EndpointReference<code> as a <code>String</code> 
+	 */
+	public void setAppliesTo(String appliesTo) {
+	  	if(this.appliesToElement == null) {
+	  		this.appliesToElement = new AppliesTo(this.element.getOwnerDocument());
+	  		this.element.appendChild(this.appliesToElement.getElement());
+	  	}
+
+	  	this.appliesToElement.setEndpointReference(appliesTo);
+	}
+  
+	/**
+	 * Sets the <code>wst:Entropy/wst:BinarySecret</code> value and 
+	 * <code>wst:Entropy/wst:BinarySecret@Type</code> of the 
+	 * <code>wst:RequestSecurityToken</code>
+	 * @param binarySecretType 
+	 * @param entropyValue
+	 */
+	public void setEntropy(String binarySecretType, String entropyValue) {
+	  	if(this.entropyElement == null) {
+	  		this.entropyElement = new Entropy(this.document);
+	  		this.addChild(this.entropyElement);
+	  	}
+	  	
+	  	this.entropyElement.setBinarySecret(binarySecretType,entropyValue);
+		
+	}
+  
+	/**
+	 * Sets the binary secret of the Entropy element when the its of type <code>Nonce</code>
+	 * @see BinarySecret#NONCE_VAL
+	 * @param entropyValue The nonce value
+	 */
+	public void setEntropyNonce(String nonceValue) {
+		this.setEntropy(TrustConstants.BINARY_SECRET_NONCE_VAL,nonceValue);
+	}
+	
+	/**
+	 * Adds a <code>wst:Lifetime</code> element with the given duration to the 
+	 * <code>wst:RequestSecurityToken</code>
+	 * @param duration
+	 */
+	public void setLifetime(int duration) {
+	  	if(this.lifetimeElement == null)
+	  		this.removeChild(this.lifetimeElement);
+	  	this.lifetimeElement = new Lifetime(this.document,duration);
+	}
+	
+	/**
+	 * Sets the <code>wst:KeySize</code> value of the <code>wst:RequestSecurityToken</code>
+	 * @param size
+	 */
+	public void setKeySize(int size) {
+	  	if(this.keySizeElement == null) {
+	  		this.keySizeElement = new KeySize(this.document);
+	  		this.addChild(this.keySizeElement);
+	  	}
+	  		
+	  	this.keySizeElement.setKeySize(size);
+	}
+	
+	
+	/**
+	 * Sets the values of the <code>wst:Claims</code> element of the 
+	 * <code>wst:RequestSecurityToken</code>
+	 * @param dialectURI
+	 * @param claimsElement An <code>Element</code> representing a claim
+	 */
+	public void setClaims(String dialectURI, Element claimsElement) {
+		if(this.claimsElement == null){
+			this.claimsElement = new Claims(this.document);
+			this.addChild(this.claimsElement);
+		}
+		
+		this.claimsElement.setDialectAttribute(dialectURI);
+		this.claimsElement.addToken(claimsElement);
+	}
+
+	/**
+	 * Sets a set of claims
+	 * @param dialectURI
+	 * @param claims
+	 */
+	public void setClaims(String dialectURI, NodeList claims) {
+		if(this.claimsElement == null){
+			this.claimsElement = new Claims(this.document);
+			this.addChild(this.claimsElement);
+		}
+		
+		this.claimsElement.setDialectAttribute(dialectURI);
+		this.claimsElement.addClaims(claims);
+	}
+	
+	/**
+	 * Sets the dialect attribute value of the <code>wst:Claims</code> element
+	 * @param dialectURI
+	 */
+	public void setClaimsDialectAttr(String dialectURI) {
+		if(this.claimsElement == null){
+			this.claimsElement = new Claims(this.document);
+			this.addChild(this.claimsElement);
+		}
+		
+		this.claimsElement.setDialectAttribute(dialectURI);
+	}
+	
+	/**
+	 * Sets the <code>wst:Renewing</code> element of the 
+	 * <code>wst:RequestSecurityToken</code>
+	 * @param allow
+	 * @param ok
+	 */
+	public void setRenewing(boolean allow, boolean ok) {
+		if(this.renewingElement == null) {
+			this.renewingElement = new Renewing(this.document);
+			this.addChild(this.renewingElement);
+		}
+		
+		this.renewingElement.setAllow(allow);
+		this.renewingElement.setOK(ok);
+	}
+	
+
+	/**
+	 * Returns the <code>AppliesTo</code> element
+	 * @return
+	 */
+	public AppliesTo getAppliesToElement() {
+		return appliesToElement;
+	}
+	
+	/**
+	 * Returns the <code>Claims</code> element
+	 * @return
+	 */
+	public Claims getClaimsElement() {
+		return claimsElement;
+	}
+	
+	/**
+	 * Returns the <code>Entropy</code> element
+	 * @return
+	 */
+	public Entropy getEntropyElement() {
+		return entropyElement;
+	}
+	
+	/**
+	 * Returns the <code>KeySize</code> element
+	 * @return
+	 */
+	public KeySize getKeySizeElement() {
+		return keySizeElement;
+	}
+	
+	/**
+	 * Returns the <code>Lifetime</code>
+	 * @return
+	 */
+	public Lifetime getLifetimeElement() {
+		return lifetimeElement;
+	}
+	
+	/**
+	 * Returns the <code>Renewing</code> element
+	 * @return
+	 */
+	public Renewing getRenewingElement() {
+		return renewingElement;
+	}
+	
+	/**
+	 * Handle the serialization of child elements specific to this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.RequestSecurityToken#handleSpecificChildren(org.w3c.dom.Element)
+	 */
+	protected void handleSpecificChildren(Element elem) throws WSTrustException {
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+		if(el.equals(AppliesTo.TOKEN)) {
+			this.appliesToElement = new AppliesTo(elem);
+		} else if(el.equals(Claims.TOKEN)) {
+			this.claimsElement = new Claims(elem);			
+		} else if(el.equals(Entropy.TOKEN)) {
+			this.entropyElement = new Entropy(elem);
+		} else if(el.equals(Lifetime.TOKEN)) {
+			this.lifetimeElement = new Lifetime(elem);
+		} else if(el.equals(KeySize.TOKEN)) {
+			this.keySizeElement = new KeySize(elem);
+		} else if(el.equals(Renewing.TOKEN)) {
+			this.renewingElement = new Renewing(elem);
+		} else {
+        	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+        			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+					new Object[] {
+        			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+					el.getNamespaceURI(),el.getLocalPart()});
+		}
+		
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/KeySize.java b/src/org/apache/ws/sandbox/security/trust/message/token/KeySize.java
new file mode 100644
index 0000000..833ed4a
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/KeySize.java
@@ -0,0 +1,70 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Ruchith Fernando
+ */
+public class KeySize extends ValueElement {
+
+    
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS,TrustConstants.KEY_SIZE_LN,TrustConstants.WST_PREFIX);
+
+    public KeySize(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    public KeySize(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Sets the key size value of the <code>wst:KeySize</code> element
+     * @param keySize
+     */
+    public void setKeySize(int keySize) {
+    	
+    	this.setValue(Integer.toString(keySize));
+    }
+
+    /**
+     * Returns the key size if set otherwise returns -1
+     * @return Returns the key size if set otherwise returns -1
+     * @throws WSTrustException
+     */
+    public int getKeySize() {
+        if(this.getValue() != null)
+        	return Integer.parseInt(this.getValue());
+        else
+        	return -1;
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Lifetime.java b/src/org/apache/ws/sandbox/security/trust/message/token/Lifetime.java
new file mode 100644
index 0000000..7f6836d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Lifetime.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ *         Lifetime token
+ */
+
+public class Lifetime extends CompositeElement {
+    
+    private Created createdElement;
+    private Expires expiresElement;
+
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.LIFE_TIME_LN, TrustConstants.WST_PREFIX);
+    
+    /**
+     * Constructor for Lifetime
+     *
+     * @param doc
+     * @param created
+     * @param expires
+     */
+    public Lifetime(Document doc, String created, String expires) {
+    	super(doc);
+
+    	this.createdElement = new Created(doc);
+    	this.createdElement.setValue(created);
+    	this.addChild(createdElement);
+    	
+    	this.expiresElement = new Expires(doc);
+    	this.expiresElement.setValue(expires);
+    	this.addChild(this.expiresElement);
+    }
+
+    /**
+     * Constructor for Lifetime
+     * Check for created and epires elements
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public Lifetime(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for Lifetime
+     *
+     * @param doc
+     * @param duration in minutes
+     */
+    public Lifetime(Document doc, int duration) {
+    	super(doc);
+    	
+        SimpleDateFormat sdtf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        sdtf.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+        Calendar rightNow = Calendar.getInstance();
+        Calendar expires = Calendar.getInstance();
+        
+        this.createdElement = new Created(doc);
+        this.createdElement.setValue(sdtf.format(rightNow.getTime()));
+        this.addChild(this.createdElement);
+        
+        this.expiresElement = new Expires(doc);
+        long exp = rightNow.getTime().getTime() + duration * 1000 * 60;
+        expires.setTimeInMillis(exp);
+        this.expiresElement.setValue(sdtf.format(expires.getTime()));
+        this.addChild(this.expiresElement);
+    }
+    
+    /**
+     * Retuns the value of the <code>wsu:Created</code> child element 
+     * @return
+     */
+    public String getCreated() {
+    	if(this.createdElement != null)
+    		return this.createdElement.getValue();
+    	else
+    		return null;
+    }
+
+    /**
+     * Returns the value of the <code>wsu:Expires</code> element
+     * @return
+     */
+    public String getExpires() {
+    	if(this.expiresElement!= null)
+    		return this.expiresElement.getValue();
+    	else
+    		return null;
+    }
+
+    /**
+     * Sets the value of the <code>wsu:Created</code>element
+     * @param value
+     */
+    public void setCreated(String value) {
+    	if(this.createdElement != null)
+    		this.createdElement.setValue(value);
+    	else { 
+    		this.createdElement = new Created(this.document);
+    		this.createdElement.setValue(value);
+    		this.addChild(this.createdElement);
+    	}
+    }
+
+    /**
+     * Sets the value of the <code>wsu:Expires</code> element
+     * @param value
+     */
+    public void setExpires(String value) {
+    	if(this.expiresElement != null)
+    		this.expiresElement.setValue(value);
+    	else { 
+    		this.expiresElement = new Expires(this.document);
+    		this.expiresElement.setValue(value);
+    		this.addChild(this.expiresElement);
+    	}
+    }
+    
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		  QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+	        
+	        if(el.equals(Created.TOKEN)) {
+	        	this.createdElement = new Created(elem);
+	        } else if(el.equals(Expires.TOKEN)) {
+	        	this.expiresElement = new Expires(elem);
+	        } else {
+	        	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+	        			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+						new Object[] {
+	        			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+						el.getNamespaceURI(),el.getLocalPart()});
+	        }
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Reason.java b/src/org/apache/ws/sandbox/security/trust/message/token/Reason.java
new file mode 100644
index 0000000..4b71ded
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Reason.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ *         Reason token
+ * @see org.apache.ws.sandbox.security.trust.message.token.Status
+ */
+public class Reason extends ValueElement {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.REASON_LN, TrustConstants.WST_PREFIX);
+    
+    /**
+     * Constructor for Reason
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public Reason(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for Reason
+     *
+     * @param doc
+     */
+    public Reason(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Constructor for Reason
+     *
+     * @param doc
+     * @param value
+     */
+    public Reason(Document doc, String value) {
+        super(doc);
+        this.valueText = doc.createTextNode(value);
+        this.element.appendChild(valueText);
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RenewRequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/RenewRequestSecurityToken.java
new file mode 100644
index 0000000..88f5743
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RenewRequestSecurityToken.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * This is the class to be used to enerate a RequestSecurityToken for the 
+ * RST renewal binding
+ *
+ * Additinal child elemets required for a renewal request is provided here
+ * 
+ * NOTE: This should no tbe used in requesting a renewable security token
+ * In such a situation IssueRequestSecurityToken should be used setting the
+ * renewal properties
+ * 
+ * @see org.apache.ws.sandbox.security.trust.TrustConstants#RENEW_SECURITY_TOKEN
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class RenewRequestSecurityToken extends RequestSecurityToken {
+
+	private RenewTarget renewTargetElement;
+	private AllowPostdating allowPostdatingElement;
+	
+	private Lifetime lifetimeElement;
+	
+	/**
+	 * @param doc
+	 * @param requestType
+	 */
+	public RenewRequestSecurityToken(Document doc) {
+		super(doc, TrustConstants.RENEW_SECURITY_TOKEN);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public RenewRequestSecurityToken(Element elem) throws WSTrustException {
+		super(elem);
+	}
+	
+	/**
+	 * Set a custom token as the token being renewed
+	 * @param tokenToBeRenewed
+	 */
+	public void setRenewTarget(Element tokenBeingRenewed) {
+		if(this.renewTargetElement == null) {
+			this.renewTargetElement = new RenewTarget(this.document);
+			this.addChild(this.renewTargetElement);
+		}
+		this.renewTargetElement.setTokenToBeRenewed(tokenBeingRenewed);
+	}
+	
+	/**
+	 * sets a <code>wsse:SecurityTokenReference</code> in the
+	 * <code>wst:RenewTarget</code> element
+	 * @see SecurityTokenReference
+	 * @param securityTokenReference
+	 */
+	public void setRenewTarget(SecurityTokenReference securityTokenReference) {
+		if(this.renewTargetElement == null) {
+			this.renewTargetElement = new RenewTarget(this.document);
+			this.addChild(this.renewTargetElement);
+		}
+		this.renewTargetElement.setSecurityTokenReference(securityTokenReference);
+	}
+
+	public void setAllowPostdating() {
+		if(this.allowPostdatingElement == null) {
+			this.allowPostdatingElement = new AllowPostdating(this.document);
+			this.addChild(this.allowPostdatingElement);
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.RequestSecurityToken#handleSpecificChildren(org.w3c.dom.Element)
+	 */
+	protected void handleSpecificChildren(Element elem) throws WSTrustException {
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+		if(el.equals(RenewTarget.TOKEN)) {
+			this.renewTargetElement = new RenewTarget(elem);
+		} else if(el.equals(AllowPostdating.TOKEN)) {
+			this.allowPostdatingElement = new AllowPostdating(elem);
+		} else if(el.equals(Lifetime.TOKEN)) {
+			this.lifetimeElement = new Lifetime(elem);
+		} else {
+        	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+        			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+					new Object[] {
+        			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+					el.getNamespaceURI(),el.getLocalPart()});
+		}
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RenewTarget.java b/src/org/apache/ws/sandbox/security/trust/message/token/RenewTarget.java
new file mode 100644
index 0000000..6064465
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RenewTarget.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class RenewTarget extends CompositeElement {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.RENEW_TARGET_LN, TrustConstants.WST_PREFIX);
+
+    private Element tokenToBeRenewed;
+    private SecurityTokenReference securityTokenReference;
+    
+    public RenewTarget(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+    
+    public RenewTarget(Document doc) {
+        super(doc);
+    }
+    
+	/**
+	 * Returns the <code>wsse:SecurityTokenReference</code>
+	 * @return
+	 */    
+	public SecurityTokenReference getSecurityTokenReference() {
+		return securityTokenReference;
+	}
+	
+	/**
+	 * Sets a <code>wsse:SecurityTokenReference</code>
+	 * @param securityTokenReference
+	 */
+	public void setSecurityTokenReference(SecurityTokenReference securityTokenReference) {
+		if(this.tokenToBeRenewed != null)//If there's another token remove it
+			this.element.removeChild(this.tokenToBeRenewed);
+		if(this.securityTokenReference != null)//IF there's sec tok ref remove it
+			this.element.removeChild(this.securityTokenReference.getElement());
+		this.securityTokenReference = securityTokenReference;
+		this.element.appendChild(this.securityTokenReference.getElement());
+	}
+	
+	/**
+	 * Returns the token to be renewed
+	 * @return
+	 */
+	public Element getTokenToBeRenewed() {
+		return tokenToBeRenewed;
+	}
+	
+	/**
+	 * Sets the token to be renewed
+	 * @param tokenToBeRenewed
+	 */
+	public void setTokenToBeRenewed(Element tokenToBeRenewed) {
+		if(this.securityTokenReference != null)//if there's wsse:SecurityTokenReference remove it
+			this.element.removeChild(this.securityTokenReference.getElement());
+		if(this.tokenToBeRenewed != null)//If there's some token remove it
+			this.element.removeChild(this.tokenToBeRenewed);
+		this.tokenToBeRenewed = tokenToBeRenewed;
+		this.element.appendChild(this.tokenToBeRenewed);
+	}
+	
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+        QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+        
+        QName secTokRef = new QName(WSConstants.WSSE_NS, SecurityTokenReference.SECURITY_TOKEN_REFERENCE);
+
+        if(el.equals(secTokRef) && this.tokenToBeRenewed == null) {
+        	try {
+        	this.securityTokenReference = new SecurityTokenReference(elem);
+        	} catch (WSSecurityException ex) {
+        		throw new WSTrustException(WSTrustException.INVALID_REQUEST, ex.getMessage());
+        	}
+        } else if(this.securityTokenReference == null) {
+        	this.tokenToBeRenewed = elem;
+        }
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Renewing.java b/src/org/apache/ws/sandbox/security/trust/message/token/Renewing.java
new file mode 100644
index 0000000..5b02118
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Renewing.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando 
+ * <p/>WS-Trust Spec - ..."This optional element is
+ * used to specify renew semantics for types that support this
+ * operation."...
+ * 
+ * Also can be used request for a token that can be renewed.
+ */
+public class Renewing extends AbstractToken {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.RENEWING_LN, TrustConstants.WST_PREFIX);
+    
+    //to request a renewable token.
+    boolean isAllow;
+    
+    //to indicate that a renewable token is    acceptable if the requested duration exceeds the limit of the issuance service.
+    boolean isOK;
+
+    /**
+     * Constructor for Renewing
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public Renewing(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for Renewing
+     * @param doc
+     */
+    public Renewing(Document doc) {
+        super(doc);
+        this.isAllow = true;
+        this.isOK = false;
+    }
+
+    /**
+     * Constructor for Renewing
+     *
+     * @param doc
+     * @param isOK
+     * @param isAllow
+     */
+    public Renewing(Document doc, boolean isOK, boolean isAllow) {
+        super(doc);
+        
+        this.isAllow = isAllow;
+        this.isOK = isOK;
+        
+        this.element.setAttribute(TrustConstants.RENEWING_ALLOW_ATTR, String.valueOf(this.isAllow));
+        this.element.setAttribute(TrustConstants.RENEWING_OK_ATTR, String.valueOf(this.isOK));
+    }
+
+    public void setAllow(boolean allow) {
+        this.isAllow = allow;
+        this.element.setAttribute(TrustConstants.RENEWING_ALLOW_ATTR, String.valueOf(allow));
+    }
+
+    public boolean getAllow() {
+        return this.isAllow;
+    }
+
+    public void setOK(boolean isOK) {
+        this.isOK = isOK;
+        this.element.setAttribute(TrustConstants.RENEWING_OK_ATTR, String.valueOf(isOK));
+    }
+
+    public boolean getOK() {
+        return this.isOK;
+    }
+    
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+		"There cannot be a child element in this element");
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElementText(org.w3c.dom.Text)
+	 */
+	protected void setElementTextValue(Text textNode) throws WSTrustException {
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+		"There cannot be a value in this element");
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityToken.java
new file mode 100644
index 0000000..d5ae5b5
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityToken.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public abstract class RequestSecurityToken extends CompositeElement {
+	
+    protected TokenType tokenTypeElement;
+    protected RequestType requestTypeElement;
+	
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.REQUEST_SECURITY_TOKEN_LN, TrustConstants.WST_PREFIX);
+
+	/**
+	 * Creates a new <code>wst:RequestSecurityToken</code> with the 
+	 * given request type 
+	 * @param doc
+	 * @param requestType
+	 */
+	public RequestSecurityToken(Document doc, String requestType){
+		super(doc);
+		this.setRequestType(requestType);
+	}
+	
+	/**
+	 * Instanciate a new <code>RequestSecurityToken</code> with a <code>wst:RequestSecurityToken</code> 
+	 * token's element 
+	 * @param elem 
+	 * @throws WSSecurityException
+	 */
+	public RequestSecurityToken(Element elem) throws WSTrustException{
+	  	super(elem);
+	  	//TODO  Parse and populate the elements
+	  	
+	}  
+  
+	/**
+	 * Sets the <code>wst:TokenType</code> value of this <code>wst:RequestSecurityToken</code>
+	 * @param tokenType The <code>wst:TokenType</code> uri as a <code>String</code>
+	 */
+	public void setTokenType(String tokenType) {
+	  	if(this.tokenTypeElement == null) { 
+	  		this.tokenTypeElement = new TokenType(this.element.getOwnerDocument());
+	  		this.element.appendChild(this.tokenTypeElement.getElement());
+	  	}
+
+	  	this.tokenTypeElement.setValue(tokenType);
+	  	
+	}
+
+	/**
+	 * Returns the value of the TokenType element 
+	 * @return
+	 */
+	public String getTokenType() {
+		if(this.tokenTypeElement != null)
+			return this.tokenTypeElement.getValue();
+		else
+			return null;
+	}
+
+  
+	/**
+	 * Sets the <code>wst:RequestType</code> value of this <code>wst:RequestSecurityToken</code>
+	 * @param requestType The <code>wst:RequestType</code> uri as a <code>String
+	 */
+	public void setRequestType(String requestType) {
+	  	if(this.requestTypeElement == null) {
+	  		this.requestTypeElement = new RequestType(this.element.getOwnerDocument());
+	  		this.element.appendChild(this.requestTypeElement.getElement());
+	  	}
+
+		this.requestTypeElement.setValue(requestType);
+
+	}
+
+	/**
+	 * Returns the value of the <code>RequestType</code> element
+	 * @return
+	 */
+	public String getRequesType() {
+	  	if(this.requestTypeElement != null)
+	  		return this.requestTypeElement.getValue();
+	  	else 
+	  		return null;
+	}
+  
+	public void setContextAttr(String contextAttrValue) {
+		this.element.setAttribute(TrustConstants.CONTEXT_ATTR, contextAttrValue);
+	}
+  
+	
+	/**
+	 * This is provided as an extensibility mechanism to add any
+	 * child element to the <code>wst:RequestSecyrityToken</code> element
+	 * @param childToken
+	 */
+	public void addToken(Element childToken) {
+		this.element.appendChild(childToken);
+	}
+	
+	/**
+	 * This is provided as an extensibility mechnism to 
+	 * ass any attrbute to the <code>wst:RequestSecyrityToken</code> element
+	 * @param attribute
+	 * @param value
+	 */
+	public void addAttribute(String attribute, String value) {
+		this.element.setAttribute(attribute, value);
+	}
+
+	/**
+	 * This is provided to be used to extract custom elements from the 
+	 * <code>wst:RequestSecyrityToken</code>
+	 * @param namespace
+	 * @param tagName
+	 * @return
+	 */
+	public NodeList getTokensByTagNameNS(String namespace, String tagName) {
+		return this.element.getElementsByTagNameNS(namespace, tagName);
+	}
+	
+	/**
+	 * This is to be used to retrieve the value of the 
+	 * custom attrbutes added to the 
+	 * <code>wst:RequestSecyrityToken</code>
+	 * @param attribute
+	 * @return
+	 */
+	public String getAttributeValue(String attribute) {
+		return this.element.getAttribute(attribute);		
+	}
+	
+	/**
+	 * Returns the QName of this type
+	 * 
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/**
+	 * Returns the root element of this token
+	 * TODO: This should be removed
+	 */
+	public Element getElement() {
+		return this.element;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException {
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+		if(el.equals(RequestType.TOKEN)) {
+			this.requestTypeElement = new RequestType(elem);
+		} else if(el.equals(TokenType.TOKEN)) {
+			this.tokenTypeElement = new TokenType(elem);
+		} else {
+			this.handleSpecificChildren(elem);
+		}
+		
+	}
+	
+	/**
+	 * This is used to handle the specific child elements for the 
+	 * four types of requests
+	 * <ul>
+	 * <li>Issue</li> @see TrustConstants#ISSUE_SECURITY_TOKEN
+	 * <li>Renew</li> @see TrustConstants#RENEW_SECURITY_TOKEN
+	 * <li>Cancel</li> @see TrustConstants#CANCEL_SECURITY_TOKEN
+	 * <li>Validate</li> @see TrustConstants#VALIDATE_SECURITY_TOKEN
+	 * </ul>
+	 * @param elem
+	 * @throws WSTrustException
+	 */
+	protected abstract void handleSpecificChildren(Element elem) throws WSTrustException;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityTokenResponse.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityTokenResponse.java
new file mode 100644
index 0000000..2776fe1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestSecurityTokenResponse.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.axis.components.logger.LogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.namespace.QName;
+
+public class RequestSecurityTokenResponse extends CompositeElement {
+	
+    private static Log log = LogFactory.getLog(RequestSecurityTokenResponse.class.getName());
+
+    private RequestedSecurityToken requestedSecurityToken;
+    private RequestedProofToken requestedProofToken;
+
+    private TokenType tokenTypeElement;
+    private Lifetime lifeTimeElement;
+
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.REQUEST_SECURITY_TOKEN_RESPONSE_LN, TrustConstants.WST_PREFIX);
+    //
+    /**
+     * Constructor
+     *
+     * @param doc
+     * @throws java.lang.Exception
+     */
+    public RequestSecurityTokenResponse(Document doc) throws Exception {
+    	super(doc);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param doc
+     * @throws java.lang.Exception
+     */
+    public RequestSecurityTokenResponse(Document doc, boolean generateChildren) throws Exception {
+        this(doc);
+        if (generateChildren) {
+            this.requestedSecurityToken = new RequestedSecurityToken(doc, true);
+            this.requestedProofToken = new RequestedProofToken(doc);
+            this.element.appendChild(requestedSecurityToken.getElement());//ruchith
+            this.element.appendChild(requestedProofToken.getElement());//dimuthu
+        }
+    }
+
+    /**
+     * To create a RequestSecurityTokenResponse token form an element passed
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public RequestSecurityTokenResponse(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * May not be usefull in future developments.
+     * Always try to use parseChildElements as false
+     *
+     * @param elem
+     * @param setChildElement
+     * @throws WSSecurityException
+     */
+    public RequestSecurityTokenResponse(Element elem, boolean parseChildElements) throws WSTrustException {
+        this(elem);
+        if (!parseChildElements) {
+            return;
+        }
+        //TODO: This should be removed - parsing the child elements should eb teh default behaviour 
+        //which will be provided in the default element constructor
+    }
+
+    public void setContextAttr(String context) {
+        this.element.setAttribute(TrustConstants.CONTEXT_ATTR, context);
+    }
+
+    public String getContextAttr() {
+        return this.element.getAttribute(TrustConstants.CONTEXT_ATTR);
+    }
+
+    /**
+     * @return
+     */
+    public RequestedProofToken getRequestedProofToken() {
+        return requestedProofToken;
+    }
+
+    /**
+     * @return
+     */
+    public RequestedSecurityToken getRequestedSecurityToken() {
+        return requestedSecurityToken;
+    }
+
+    /**
+     * TODO: Should be removed
+     * @param doc
+     */
+    public void build(Document doc) {
+        Element securityHeader = WSSecurityUtil.findWsseSecurityHeaderBlock(doc, doc.getDocumentElement(), true);
+        WSSecurityUtil.appendChildElement(doc, securityHeader, this.element);
+
+        if (log.isInfoEnabled()) {
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(doc, os, true);
+            String osStr = os.toString();
+        }
+    }
+    
+	
+	/**
+	 * This is provided as an extensibility mechanism to add any child element 
+	 * @param childToken
+	 */
+	public void addToken(Element childToken) {
+		this.element.appendChild(childToken);
+	}
+	
+	/**
+	 * This is provided as an extensibility mechnism to as any attrbute 
+	 * @param attribute
+	 * @param value
+	 */
+	public void addAttribute(String attribute, String value) {
+		this.element.setAttribute(attribute, value);
+	}
+
+	/**
+	 * This is provided to be used to extract custom elements
+	 * @param namespace
+	 * @param tagName
+	 * @return
+	 */
+	public Element getTokenByTagNameNS(String namespace, String tagName) {
+		return (Element)this.element.getElementsByTagNameNS(namespace, tagName);
+	}
+	
+	/**
+	 * This is to be used to retrieve the value of the 
+	 * custom attrbutes added
+	 * @param attribute
+	 * @return
+	 */
+	public String getAttributeValue(String attribute) {
+		return this.element.getAttribute(attribute);		
+	}
+    
+    
+	/**
+	 * Returns the QName of this type
+	 * 
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) {
+		// TODO Auto-generated method stub
+		
+	}
+
+    
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestType.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestType.java
new file mode 100644
index 0000000..2a214d3
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestType.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ *         <p/>
+ *         RequestType token
+ */
+public class RequestType extends ValueElement {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.REQUEST_TYPE_LN, TrustConstants.WST_PREFIX);
+ 
+    /**
+     * Constructor for RequestType
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public RequestType(Element elem) throws WSTrustException {
+        super(elem);
+    }
+
+    /**
+     * Constructor for RequestType
+     *
+     * @param doc
+     */
+    public RequestType(Document doc) {
+        super(doc);
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestedProofToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedProofToken.java
new file mode 100644
index 0000000..728a71c
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedProofToken.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.WSEncryptBody;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.Loader;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+
+/**
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ * @author Ruchith Fernando
+ */
+public class RequestedProofToken {
+    private static Log log =
+            LogFactory.getLog(RequestedProofToken.class.getName());
+
+    public static final QName TOKEN =
+            new QName(TrustConstants.WST_NS, "RequestedProofToken");
+
+    private Element element;
+    private byte[] sharedSecret;
+
+    /**
+     * Constructor.
+     *
+     * @param doc    is the SOAP envelop.
+     * @throws WSSecurityException
+     */
+    public RequestedProofToken(Document doc) throws WSSecurityException {
+        this.element = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + ":" + TOKEN.getLocalPart());
+        WSSecurityUtil.setNamespace(this.element, TOKEN.getNamespaceURI(), TrustConstants.WST_PREFIX);
+        this.element.appendChild(doc.createTextNode(""));
+        log.debug("RequestedProofToken : Document constructor, Element created.");
+    }
+
+    /**
+     * COnstructor
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public RequestedProofToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType00", new Object[]{el});
+        }
+
+        log.debug("RequestedProofToken :: Element constructor, Element created.");
+    }
+
+    /**
+     * Method doDecryption
+     *
+     * @param callback
+     * @param crypto
+     * @throws WSSecurityException
+     */
+    public void doDecryption(String callback, Crypto crypto)
+            throws WSSecurityException {
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        CallbackHandler cbHandler;
+
+        // Element
+        NodeList ndList =
+                this.element.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#",
+                        "EncryptedKey");
+        if (ndList.getLength() < 1) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "RequestedProofToken is empty");
+        }
+
+        // CbHandler :: taken from WSSecurityEngine class
+        if (callback != null) {
+            Class cbClass = null;
+            try {
+                cbClass = Loader.loadClass(callback);
+            } catch (ClassNotFoundException e) {
+                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                        "RequestedProofToken: cannot load password callback class: "
+                        + callback);
+            }
+            try {
+                cbHandler = (CallbackHandler) cbClass.newInstance();
+            } catch (java.lang.Exception e) {
+                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                        "RequestedProofToken: cannot create instance of password callback: "
+                        + callback +":: ErrMsg "+e.getMessage());
+            }
+            EncryptedKeyProcessor processor = new EncryptedKeyProcessor();
+            processor.handleEncryptedKey((Element) ndList.item(0),
+                    cbHandler,
+                    crypto);
+
+            this.sharedSecret = processor.getDecryptedBytes();
+            log.debug(" RequestedProofToken, decryption ,Shared secret is :: " + new String(this.sharedSecret));
+        } else {
+            log.debug("RequestedProofToken :: CallbackHandler is null");
+            throw new WSSecurityException(WSSecurityException.FAILURE, "CallbackHandler is null");
+        }
+        log.debug("RequestedProofToken :: Encryption done");
+    }
+
+    /**
+     * Method doEncryptProof
+     *
+     * @param doc
+     */
+    //TODO :: Change the method signature.
+    public void doEncryptProof(Document doc, Crypto crypto, String userInfo) throws WSSecurityException {
+        WSEncryptBody wsEncrypt = new WSEncryptBody();
+        try {
+            wsEncrypt.setUserInfo(userInfo);
+            wsEncrypt.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+            wsEncrypt.setParentNode(this.element);
+            if (this.sharedSecret != null) {
+                //wsEncrypt.setSymmetricKey(WSSecurityUtil.prepareSecretKey(WSConstants.TRIPLE_DES, this.sharedSecret));//TODO
+            }
+//            wsEncrypt.setParentNode(
+//                (Element) (doc
+//                    .getElementsByTagNameNS(
+//                        WSConstants.WSSE_NS,
+//                        "RequestedProofToken")
+//                    .item(0)));
+            wsEncrypt.build(doc, crypto);
+            this.sharedSecret = wsEncrypt.getEncryptionKey().getEncoded();
+        } catch (WSSecurityException e) {
+            e.printStackTrace();
+        }
+        log.debug("RequestedProofToken :: Decryption Done");
+    }
+
+    public Element getElement() {
+        return element;
+    }
+
+    public void setElement(Element element) {
+        this.element = element;
+    }
+
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    public void addToken(Element childToken) {
+        this.element.appendChild(childToken);
+    }
+
+    public void removeToken(Element childToken) {
+        this.element.removeChild(childToken);
+    }
+
+    /**
+     * @return
+     */
+    public byte[] getSharedSecret() {
+        return sharedSecret;
+    }
+
+    /**
+     * @param bs
+     */
+    public void setSharedSecret(byte[] bs) {
+        sharedSecret = bs;
+    }
+
+    public Document build(Document doc, Crypto crypto, String user, Element parentNode) throws WSSecurityException {
+        boolean doDebug = log.isDebugEnabled();
+        //TODO
+        int keyIdentifierType = WSConstants.ISSUER_SERIAL;
+        SecretKey symmetricKey = null;
+        String symEncAlgo = WSConstants.TRIPLE_DES;
+        String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;
+
+        if (doDebug) {
+            log.debug("Beginning Encryption...");
+        }
+
+        /*
+         * First step: set the encryption encoding namespace in the SOAP:Envelope
+         */
+        Element envelope = doc.getDocumentElement();
+        envelope.setAttributeNS(WSConstants.XMLNS_NS,
+                "xmlns:" + WSConstants.ENC_PREFIX,
+                WSConstants.ENC_NS);
+
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
+
+        /*
+         * Second step: generate a symmetric key (session key) for
+         * this alogrithm, and set the cipher into encryption mode.
+         */
+        KeyGenerator keyGen = null;
+        try {
+            keyGen = keyGen = KeyGenerator.getInstance("DESede");
+        } catch (NoSuchAlgorithmException e2) {
+            // TODO Auto-generated catch block
+            e2.printStackTrace();
+        }
+        symmetricKey = keyGen.generateKey();
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(symEncAlgo);
+        } catch (XMLEncryptionException e3) {
+            throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);
+        }
+
+
+        /*
+         * Fifth step: get the certificate that contains the public key for the
+         * public key algorithm that will encrypt
+         * the generated symmetric (session) key.
+         * Up to now we support RSA 1-5 as public key algorithm
+         */
+
+        X509Certificate remoteCert = null;
+        X509Certificate[] certs = crypto.getCertificates(user);
+        if (certs == null || certs.length <= 0) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidX509Data",
+                    new Object[]{"for Encryption"});
+        }
+        remoteCert = certs[0];
+
+        String certUri = "EncCertId-" + remoteCert.hashCode();
+
+        Cipher cipher = null;//TODO
+        //Cipher cipher = WSSecurityUtil.getCiperInstance(keyEncAlgo);//TODO
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e);
+        }
+        byte[] encKey = symmetricKey.getEncoded();
+        if (doDebug) {
+            log.debug("cipher blksize: "
+                    + cipher.getBlockSize()
+                    + ", symm key length: "
+                    + encKey.length);
+        }
+        if (cipher.getBlockSize() < encKey.length) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyTransp",
+                    new Object[]{"public key algorithm too weak to encrypt symmetric key"});
+        }
+        byte[] encryptedKey = null;
+        try {
+            encryptedKey = cipher.doFinal(encKey);
+        } catch (IllegalStateException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        } catch (IllegalBlockSizeException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        } catch (BadPaddingException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        }
+        Text keyText =
+                WSSecurityUtil.createBase64EncodedTextNode(doc, encryptedKey);
+
+        Element xencEncryptedKey = WSEncryptBody.createEnrcyptedKey(doc, keyEncAlgo);
+
+        WSSecurityUtil.prependChildElement(doc,
+                parentNode,
+                xencEncryptedKey,
+                true);
+
+        SecurityTokenReference secToken = null;//new SecurityTokenReference(doc); TODO
+
+        switch (keyIdentifierType) {
+            case WSConstants.X509_KEY_IDENTIFIER:
+                secToken.setKeyIdentifier(remoteCert);
+                // build a key id class??
+                break;
+
+            case WSConstants.SKI_KEY_IDENTIFIER:
+                secToken.setKeyIdentifierSKI(remoteCert, crypto);
+                break;
+
+            case WSConstants.ISSUER_SERIAL:
+                XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
+                X509Data x509Data = new X509Data(doc); 
+                x509Data.add(data);
+                secToken.setX509IssuerSerial(x509Data);
+                WSSecurityUtil.setNamespace(secToken.getElement(), WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
+                break;
+
+            case WSConstants.BST_DIRECT_REFERENCE:
+                BinarySecurity bstToken = null;
+                bstToken = new X509Security(doc);
+                ((X509Security) bstToken).setX509Certificate(remoteCert);
+                bstToken.setID(certUri);
+                Reference ref = new Reference(doc);
+                ref.setURI("#" + certUri);
+                ref.setValueType(bstToken.getValueType());
+                secToken.setReference(ref);
+//                WSSecurityUtil.prependChildElement(
+//                    doc,
+//                    wsseSecurity,
+//                    bstToken.getElement(),
+//                    false);
+                break;
+
+            default :
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "unsupportedKeyId");
+        }
+        KeyInfo keyInfo = new KeyInfo(doc);
+        keyInfo.addUnknownElement(secToken.getElement());
+        WSSecurityUtil.appendChildElement(doc, xencEncryptedKey, keyInfo.getElement());
+
+        Element xencCipherValue = WSEncryptBody.createCipherValue(doc, xencEncryptedKey);
+        xencCipherValue.appendChild(keyText);
+        //    createDataRefList(doc, xencEncryptedKey, encDataRefs);
+        log.debug("Encryption complete.");
+        return doc;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestedSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedSecurityToken.java
new file mode 100644
index 0000000..98353b3
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedSecurityToken.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class RequestedSecurityToken {
+
+    // private SecurityContextToken securityContextToken;
+	private Element element;
+    
+    public static final QName TOKEN =
+            new QName(TrustConstants.WST_NS,
+                    TrustConstants.REQUESTED_SECURITY_TOKEN_LN);
+    //for customUsage only
+    // No getters and setters will be generated for these members
+    SecurityContextToken sct;
+    UsernameToken unt;
+
+    /**
+     * Constructor
+     *
+     * @param doc
+     */
+    public RequestedSecurityToken(Document doc) throws Exception {
+
+        this.element =
+                doc.createElementNS(TOKEN.getNamespaceURI(),
+                        TrustConstants.WST_PREFIX + ":" + TOKEN.getLocalPart());
+
+        WSSecurityUtil.setNamespace(this.element,
+                TOKEN.getNamespaceURI(),
+                TrustConstants.WST_PREFIX);
+
+        this.element.appendChild(doc.createTextNode(""));
+
+    }
+
+    /**
+     * Constructor
+     *
+     * @param doc
+     */
+    public RequestedSecurityToken(Document doc, boolean generateChildren) throws Exception {
+        this(doc);
+        if (generateChildren) {
+            this.sct = new SecurityContextToken(doc);
+            this.element.appendChild(sct.getElement());
+
+        }
+    }
+
+    /**
+     * To create a RequestSecurityTokenResponse token form an element passed
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public RequestedSecurityToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el =
+                new QName(this.element.getNamespaceURI(),
+                        this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType00",
+                    new Object[]{el});
+        }
+    }
+
+    /**
+     * May not be usefull in future developments.
+     * Always try to use parseChildElements as false
+     *
+     * @param elem
+     * @param parseChildElements
+     * @throws WSSecurityException
+     */
+
+    public RequestedSecurityToken(Element elem, boolean parseChildElements)
+            throws WSSecurityException {
+        this(elem);
+        if (!parseChildElements) {
+            return;
+        }
+
+        this.sct =
+                new SecurityContextToken((Element) WSSecurityUtil.getDirectChild(//elem.getOwnerDocument(),
+                        elem,
+                        SecurityContextToken.TOKEN.getLocalPart(),
+                        SecurityContextToken.TOKEN.getNamespaceURI()));
+
+    }
+
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * @return
+     */
+    public Element getElement() {
+        return element;
+    }
+
+    public void setElement(Element element) {
+        this.element = element;
+    }
+
+    public void addToken(Element childToken) {
+        this.element.appendChild(childToken);
+    }
+
+    /**
+     * @return
+     */
+    public SecurityContextToken getSct() {
+        return sct;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/RequestedTokenCancelled.java b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedTokenCancelled.java
new file mode 100644
index 0000000..5bd2230
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/RequestedTokenCancelled.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class RequestedTokenCancelled extends AbstractToken {
+
+	
+	public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.REQUESTED_TOKEN_CANCELLED_LN, TrustConstants.WST_PREFIX);
+	
+	/**
+	 * @param doc
+	 */
+	public RequestedTokenCancelled(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public RequestedTokenCancelled(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElementText(org.w3c.dom.Text)
+	 */
+	protected void setElementTextValue(Text textNode) {
+		// TODO Auto-generated method stub
+		
+	}
+
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/STSSignedToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/STSSignedToken.java
new file mode 100644
index 0000000..d666a9e
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/STSSignedToken.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.signature.XMLSignature;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         Specially for usage of STS.
+ *         Token Issuer developers can use this class to get their token signed.
+ *         The cannonicalization algorithm used here is <code>http://www.w3.org/2001/10/xml-exc-c14n#</code>.
+ *         <p/>
+ *         According to the public key algorithm the signature algorithm is recognized.
+ *         There are two such algorithms that are supported here.
+ *         They are
+ *         1.    http://www.w3.org/2000/09/xmldsig#dsa-sha1
+ *         2.    http://www.w3.org/2000/09/xmldsig#rsa-sha1
+ *         <p/>
+ *         If the public key algorithm is not supported then a <code>WSSecurityException</code> is thrown.
+ *         Else it creates an <code>XMLSignature</code> and signs it using private key of the Security Token Service
+ */
+
+public class STSSignedToken {
+
+    private Element element;
+
+    /**
+     * @param docTobeSigned the document to be signed
+     * @param crypto
+     * @param alias         alias of the x509 certificate
+     * @param password      password of that particular certificate of the keystore
+     * @throws WSSecurityException
+     */
+    public STSSignedToken(Document docTobeSigned, Crypto crypto, String alias, String password) throws WSSecurityException {
+
+        X509Certificate[] certs = crypto.getCertificates(alias);
+
+        String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
+        String sigAlgo = "";
+        String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+        if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+        } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
+            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
+        } else {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidX509Data",
+                    new Object[]{"for Signature - unkown public key Algo"});
+        }
+
+        XMLSignature sig = null;
+        try {
+            sig = new XMLSignature(docTobeSigned, null, sigAlgo, canonAlgo);
+            sig.addKeyInfo(certs[0]);
+            sig.sign(crypto.getPrivateKey(alias, password));
+        } catch (XMLSecurityException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    "UserNAmeTokenIssuer:signature over token failed");
+
+        } catch (Exception e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    "UserNAmeTokenIssuer:signature over token failed. General exception-kau");
+        }
+
+        this.element = sig.getElement();
+    }
+
+    /**
+     * @return the signature element
+     */
+    public Element getElement() {
+        return element;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/Status.java b/src/org/apache/ws/sandbox/security/trust/message/token/Status.java
new file mode 100644
index 0000000..41c65ab
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/Status.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ */
+public class Status extends CompositeElement {
+	
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.STATUS_LN, TrustConstants.WST_PREFIX);
+    
+    private Code codeElement;
+    private Reason reasonElement;
+    
+
+    /**
+     * Constructor for Status
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public Status(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for Status
+     *
+     * @param doc
+     */
+    public Status(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Sets the code of the status
+     *
+     * @param code
+     */
+    public void setCode(String codeValue) {
+    	if(this.codeElement != null) //If there's a value already set, remove that element
+    		this.element.removeChild(this.codeElement.getElement());
+
+    	this.codeElement = new Code(this.element.getOwnerDocument());
+    	this.codeElement.setValue(codeValue);
+    	this.element.appendChild(this.codeElement.getElement());
+    }
+
+    /**
+     * Gets the code of the status
+     *
+     * @return
+     * @throws WSSecurityException
+     */
+    public String getCode() {
+        if(this.codeElement != null)
+        	return this.codeElement.getValue();
+        else
+        	return null;
+    }
+
+    /**
+     * Sets the reason of the status
+     *
+     * @param reason
+     */
+    public void setReason(String reason) {
+        if(this.reasonElement != null)
+        	this.element.removeChild(this.reasonElement.getElement());
+        
+        this.reasonElement = new Reason(this.element.getOwnerDocument());
+        this.reasonElement.setValue(reason);
+        this.element.appendChild(this.reasonElement.getElement());
+    }
+
+    /**
+     * Gets the reason of the status
+     *
+     * @return
+     * @throws WSSecurityException
+     */
+    public String getReason() {
+    	if(this.reasonElement != null)
+    		return this.reasonElement.getValue();
+    	else
+    		return null;
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem) throws WSTrustException{
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		if(el.equals(Code.TOKEN)) {
+			this.codeElement = new Code(elem);
+		} else if(el.equals(Reason.TOKEN)) {
+			this.reasonElement = new Reason(elem);
+		} else {        	
+			throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+    			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+				new Object[] {
+    			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+				el.getNamespaceURI(),el.getLocalPart()});
+		}
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/TokenType.java b/src/org/apache/ws/sandbox/security/trust/message/token/TokenType.java
new file mode 100644
index 0000000..f4195e8
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/TokenType.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Malinda Kaushalye
+ * @author Ruchith Fernando
+ *         <p/>
+ *         TokenType element
+ */
+public class TokenType extends ValueElement {
+	
+    public static final String UNT = "http://schemas.xmlsoap.org/ws/2004/04/security/sc/unt";
+    public static final String SCT = "http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct";
+
+    public static final QName TOKEN = new QName(TrustConstants.WST_NS, TrustConstants.TOKEN_TYPE_LN, TrustConstants.WST_PREFIX);
+    
+
+    /**
+     * Constructor for TokenType
+     *
+     * @param elem
+     * @throws WSSecurityException
+     */
+    public TokenType(Element elem) throws WSTrustException {
+    	super(elem);
+    }
+
+    /**
+     * Constructor for TokenType
+     *
+     * @param doc
+     */
+    public TokenType(Document doc) {
+        super(doc);
+    }
+
+	/**
+	 * Returns the QName of this type
+	 * @see org.apache.ws.sandbox.security.trust.message.token.AbstractToken#getToken()
+	 */
+	protected QName getToken() {
+		return TOKEN;
+	}
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/ValidateRequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust/message/token/ValidateRequestSecurityToken.java
new file mode 100644
index 0000000..079b00d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/ValidateRequestSecurityToken.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.sandbox.security.trust.TrustConstants;
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+/**
+ * This is the class to be used to enerate a RequestSecurityToken for the 
+ * RST validation binding
+ * 
+ * Even though the ES-Trust spec does not directly specify any specific 
+ * child elements for this RST element, this can be used to extend the 
+ * fuctionality 
+ * 
+ * @see org.apache.ws.sandbox.security.trust.TrustConstants#RENEW_SECURITY_TOKEN
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class ValidateRequestSecurityToken extends RequestSecurityToken {
+
+	
+	/**
+	 * @param doc
+	 * @param requestType
+	 */
+	public ValidateRequestSecurityToken(Document doc) {
+		super(doc, TrustConstants.VALIDATE_SECURITY_TOKEN);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSSecurityException
+	 */
+	public ValidateRequestSecurityToken(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.RequestSecurityToken#handleSpecificChildren(org.w3c.dom.Element)
+	 */
+	protected void handleSpecificChildren(Element elem) throws WSTrustException {
+		
+		QName el =  new QName(elem.getNamespaceURI(), elem.getLocalName());
+		
+    	throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+    			WSTrustException.DESC_INCORRECT_CHILD_ELEM,
+				new Object[] {
+    			TOKEN.getPrefix(),TOKEN.getLocalPart(),
+				el.getNamespaceURI(),el.getLocalPart()});
+		
+	}
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/message/token/ValueElement.java b/src/org/apache/ws/sandbox/security/trust/message/token/ValueElement.java
new file mode 100644
index 0000000..7499b2a
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/message/token/ValueElement.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.message.token;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * This is the base class for the elements that carries a
+ * value in the element
+ * Example:
+ * 	<wsu:Created>...</wsu:Created>
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public abstract class ValueElement extends AbstractToken {
+
+	protected Text valueText;
+	
+	/**
+	 * @param doc
+	 */
+	public ValueElement(Document doc) {
+		super(doc);
+	}
+
+	/**
+	 * @param elem
+	 * @throws WSTrustException
+	 */
+	public ValueElement(Element elem) throws WSTrustException {
+		super(elem);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#deserializeChildElement(org.w3c.dom.Element)
+	 */
+	protected void deserializeChildElement(Element elem)
+			throws WSTrustException {
+		//There cannot be any children in this token
+		throw new WSTrustException(WSTrustException.INVALID_REQUEST,
+				WSTrustException.DESC_CHILD_IN_VALUE_ELEM,
+				new Object[] {
+				this.getToken().getNamespaceURI(),this.getToken().getLocalPart(),
+				elem.getNamespaceURI(),elem.getLocalName()});
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.ws.security.trust.message.token.AbstractToken#setElementTextValue(org.w3c.dom.Text)
+	 */
+	protected void setElementTextValue(Text textNode) throws WSTrustException {
+		this.valueText = textNode;
+	}
+
+	/**
+	 * Returns the value of the token
+	 * @return
+	 */
+	public String getValue() {
+		if(this.valueText != null) 
+			return this.valueText.getNodeValue();
+		else
+			return null;
+	}
+	
+	/**
+	 * Sets the value of the token
+	 * @param value
+	 */
+	public void setValue(String value) {
+    	if(this.valueText != null)
+    		this.element.removeChild(this.valueText);
+    	
+    	this.valueText = element.getOwnerDocument().createTextNode(value);
+        this.element.appendChild(this.valueText);
+	}
+	
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/renew/STRenewer.java b/src/org/apache/ws/sandbox/security/trust/renew/STRenewer.java
new file mode 100644
index 0000000..bd99cff
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/renew/STRenewer.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.renew;
+
+import org.w3c.dom.Document;
+
+public interface STRenewer {
+    public Document renew(Document req, Document res) throws Exception;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/request/STRequester.java b/src/org/apache/ws/sandbox/security/trust/request/STRequester.java
new file mode 100644
index 0000000..703704a
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/request/STRequester.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.request;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+
+import java.util.Hashtable;
+
+/**
+ * @author Malinda Kaushalye
+ *         Interface STRequester provide a way to build a request
+ *         on behalf of the client.
+ */
+public interface STRequester {
+    /**
+     * Modify request according to the given options
+     *
+     * @param req     full Envelop of the SOAP request as a Dom document
+     * @param hashOps all the paramaeters in the .wsdd file as a hash map
+     * @return modified request docment.
+     * @throws WSTrustException
+     */
+    public Document request(Document req, Hashtable hashOps) throws WSTrustException;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/validate/STValidator.java b/src/org/apache/ws/sandbox/security/trust/validate/STValidator.java
new file mode 100644
index 0000000..3e3d7bd
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/validate/STValidator.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.validate;
+
+import org.w3c.dom.Document;
+
+/**
+ * @author Malinda Kaushalye
+ *         <p/>
+ *         Builds the response message to validate the request
+ */
+public interface STValidator {
+    /**
+     * Status of the token as specified in the specification
+     */
+    public static final String VALID = "http://schemas.xmlsoap.org/ws/2004/04/security/trust/status/valid";
+    public static final String INVALID = "http://schemas.xmlsoap.org/ws/2004/04/security/trust/status/invalid";
+
+    public Document validate(Document req, Document res) throws Exception;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/verify/ClaimVerifier.java b/src/org/apache/ws/sandbox/security/trust/verify/ClaimVerifier.java
new file mode 100644
index 0000000..e5d45e3
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/verify/ClaimVerifier.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.verify;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+
+import java.util.Properties;
+
+public class ClaimVerifier implements STVerifier {
+
+    public ClaimVerifier(Properties prop) {
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.trust.verify.STVerifier#verify(org.w3c.dom.Document)
+     */
+    public boolean verify(Document doc)
+            throws WSTrustException {
+        // TODO Claims verification
+        return true;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/verify/IssuerVerifier.java b/src/org/apache/ws/sandbox/security/trust/verify/IssuerVerifier.java
new file mode 100644
index 0000000..8d7a890
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/verify/IssuerVerifier.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.verify;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+
+import java.util.Properties;
+
+public class IssuerVerifier implements STVerifier {
+
+    public IssuerVerifier(Properties prop) {
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.trust.verify.STVerifier#verify(org.w3c.dom.Document)
+     */
+    public boolean verify(Document doc)
+            throws WSTrustException {
+        // TODO Issuer verification
+        return true;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/verify/STVerifier.java b/src/org/apache/ws/sandbox/security/trust/verify/STVerifier.java
new file mode 100644
index 0000000..67749f6
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/verify/STVerifier.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.verify;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+
+/**
+ * @author Ruchith
+ *         This is the interface for three verifiers used by the Trust engine
+ */
+public interface STVerifier {
+    /**
+     * Verification for the Trust engine
+     *
+     * @param doc  The request document
+     * @param porp configuration information
+     * @return Verified/NOT ?
+     * @throws TrustException
+     */
+    public boolean verify(Document doc) throws WSTrustException;
+}
diff --git a/src/org/apache/ws/sandbox/security/trust/verify/SignatureVerifier.java b/src/org/apache/ws/sandbox/security/trust/verify/SignatureVerifier.java
new file mode 100644
index 0000000..4161bbe
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust/verify/SignatureVerifier.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust.verify;
+
+import org.apache.ws.sandbox.security.trust.WSTrustException;
+import org.w3c.dom.Document;
+
+import java.util.Properties;
+
+/**
+ * @author Ruchith
+ */
+public class SignatureVerifier implements STVerifier {
+
+    public SignatureVerifier(Properties prop) {
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.trust.verify.STVerifier#verify(org.w3c.dom.Document)
+     */
+    public boolean verify(Document doc)
+            throws WSTrustException {
+        // TODO Signature verification
+        return true;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/Lifetime.java b/src/org/apache/ws/sandbox/security/trust2/Lifetime.java
new file mode 100644
index 0000000..5c4a2bc
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/Lifetime.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For indicating the <Lifetime> associated with a token request or response.
+ *         This usually includes wsu:Created and wsu:Expires elements
+ */
+public class Lifetime extends Timestamp {
+
+    /**
+     * @param element
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public Lifetime(WSSConfig wssConfig, Document doc, Element element) throws WSSecurityException {
+        super(element);
+        this.element = copyElement(doc, element);
+    }
+
+    /**
+     * @param doc      The XML document to be used for element creation
+     * @param duration Indicates how many seconds in the future this Lifetime Expires
+     */
+    public Lifetime(WSSConfig wssConfig, Document doc, int duration) {
+        super(wssConfig.isPrecisionInMilliSeconds(), doc, duration);
+        element = changeElementName(element, TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.LIFETIME);
+    }
+
+    /**
+     * Constructs a <code>Lifetime</code> object according
+     * to the defined parameters.
+     * <p/>
+     *
+     * @param doc     The SOAP envelope as <code>Document</code>
+     * @param created The creation time for this lifetime
+     * @param expires When this lifetime expires
+     */
+    public Lifetime(WSSConfig wssConfig, Document doc, Date created, Date expires) {
+        super(wssConfig.isPrecisionInMilliSeconds(), doc, 0);
+
+        element = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.LIFETIME);
+        WSSecurityUtil.setNamespace(element, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+
+        SimpleDateFormat zulu = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
+        Calendar rightNow = Calendar.getInstance();
+        if (created == null)
+            created = rightNow.getTime();
+
+        Element elementCreated = doc.createElementNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN);
+        WSSecurityUtil.setNamespace(elementCreated, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+        elementCreated.appendChild(doc.createTextNode(zulu.format(created)));
+        element.appendChild(elementCreated);
+
+        if (expires == null)
+            expires = created;
+
+        Element elementExpires = doc.createElementNS(WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN);
+        WSSecurityUtil.setNamespace(elementExpires, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+        elementExpires.appendChild(doc.createTextNode(zulu.format(expires)));
+        element.appendChild(elementExpires);
+
+        this.created = Calendar.getInstance();
+        this.expires = Calendar.getInstance();
+        this.created.setTime(created);
+        this.expires.setTime(expires);
+    }
+
+    public Element getElement(Document doc) {
+        return copyElement(doc, element);
+    }
+
+    protected Element copyElement(Document doc, Element oldElement) {
+        // Make a copy of the element subtree suitable for inserting into doc
+        return (Element) doc.importNode(oldElement, true);
+    }
+
+    protected Element changeElementName(Document doc, Element oldElement, String newNamespace, String newQualName) {
+        // Create an element with the new name
+        Element element2 = doc.createElementNS(newNamespace, newQualName);
+    
+        // Copy the attributes to the new element
+        NamedNodeMap attrs = oldElement.getAttributes();
+        for (int i = 0; i < attrs.getLength(); i++) {
+            Attr attr2 = (Attr) doc.importNode(attrs.item(i), true);
+            element2.getAttributes().setNamedItem(attr2);
+        }
+    
+        // Move all the children
+        while (oldElement.hasChildNodes()) {
+            element2.appendChild(oldElement.getFirstChild());
+        }
+
+        return element2;
+    }
+
+    protected Element changeElementName(Element oldElement, String newNamespace, String newQualName) {
+        return changeElementName(oldElement.getOwnerDocument(), oldElement, newNamespace, newQualName);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/RequestSecurityToken.java b/src/org/apache/ws/sandbox/security/trust2/RequestSecurityToken.java
new file mode 100644
index 0000000..2851ad1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/RequestSecurityToken.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.sandbox.security.trust2.exception.ElementParsingException;
+import org.apache.ws.sandbox.security.trust2.exception.NoRequestType;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RequestSecurityToken extends SecurityTokenMessage {
+
+    protected URI requestType = null;
+
+    protected SecurityTokenOrReference base = null;
+    protected List supporting = new ArrayList();
+
+    public RequestSecurityToken(Document doc, URI requestType) {
+        super(doc);
+        this.requestType = requestType;
+    }
+
+    /**
+     * Constructs a RequestSecurityToken object from an existing element.
+     *
+     * @param element
+     */
+    public RequestSecurityToken(Element element) throws ElementParsingException {
+        super(element);
+        initialize(element);
+    }
+
+    public RequestSecurityToken(Element element, Document document) throws ElementParsingException {
+        super(element, document);
+        initialize(element);
+    }
+
+    private void initialize(Element element) throws ElementParsingException {
+        ArrayList elements = (ArrayList) customElements.clone();
+        customElements.clear();
+
+        for (int i = 0; i < elements.size(); i++) {
+            Element currentNode = (Element) elements.get(i);
+
+            if (!TrustConstants.WST_NS.equals(currentNode.getNamespaceURI())) {
+                addCustomElement(currentNode);
+                continue;
+            } else if (currentNode.getLocalName().equals(TrustConstants.REQUEST_TYPE)) {
+                String textContent = getTextContent(currentNode);
+                if (textContent != null && !textContent.equals("")) {
+                    try {
+                        setRequestType(new URI(textContent));
+                    } catch (URISyntaxException e) {
+                        throw new ElementParsingException("URISyntaxException while creating RequestSecurityToken (RequestType) from XML Element: "
+                                + e.getMessage());
+                    }
+                }
+            } else if (currentNode.getLocalName().equals(TrustConstants.BASE)) {
+                Element elem = getFirstNonBlankChildAsElement(currentNode);
+                if (elem != null)
+                    setBase(new SecurityTokenOrReference(elem, doc));
+            } else if (currentNode.getLocalName().equals(TrustConstants.SUPPORTING)) {
+                NodeList supportingNodes = currentNode.getChildNodes();
+                if (supportingNodes != null) {
+                    for (int j = 0; j < supportingNodes.getLength(); j++)
+                        if (supportingNodes.item(j).getLocalName() != null)
+                            addSupporting(new SecurityTokenOrReference((Element) supportingNodes.item(j), doc));
+                }
+            } else {
+                addCustomElement(currentNode);
+            }
+        }
+    }
+
+    public void setRequestType(URI requestType) {
+        this.requestType = requestType;
+    }
+
+    public URI getRequestType() {
+        return requestType;
+    }
+
+    public void setBase(SecurityTokenOrReference base) {
+        this.base = base;
+    }
+
+    public SecurityTokenOrReference getBase() {
+        return base;
+    }
+
+    public void addSupporting(SecurityTokenOrReference supportingToken) {
+        supporting.add(supportingToken);
+    }
+
+    public List getSupporting() {
+        return supporting;
+    }
+
+    public Element getElement() throws TrustException {
+        Element wstElement = getElement(TrustConstants.WST_PREFIX + TrustConstants.REQUEST_TAG);
+
+        if (requestType != null) {
+            Element requestTypeElement = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.REQUEST_TYPE);
+            setTextContent(requestTypeElement, requestType.toString());
+            wstElement.appendChild(requestTypeElement);
+        } else {
+            throw new NoRequestType("RequestType is a required element that cannot be null.");
+        }
+
+        if (base != null) {
+            wstElement.appendChild(createTokenOrReferenceElement(TrustConstants.WST_PREFIX + TrustConstants.BASE, base));
+        }
+
+        if (!supporting.isEmpty()) {
+            Element supportingElement = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.SUPPORTING);
+
+            for (Iterator itr = supporting.iterator(); itr.hasNext();) {
+                SecurityTokenOrReference next = (SecurityTokenOrReference) itr.next();
+                supportingElement.appendChild(next.getElement());
+            }
+
+            wstElement.appendChild(supportingElement);
+        }
+        return wstElement;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/RequestSecurityTokenResponse.java b/src/org/apache/ws/sandbox/security/trust2/RequestSecurityTokenResponse.java
new file mode 100644
index 0000000..7574db1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/RequestSecurityTokenResponse.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.sandbox.security.trust2.exception.ElementParsingException;
+import org.apache.ws.sandbox.security.trust2.exception.NoTokenInResponse;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.ArrayList;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         Represents the WS-Trust <RequestSecurityTokenResponse> message which includes the requested token.
+ */
+public class RequestSecurityTokenResponse extends SecurityTokenMessage {
+
+    protected SecurityTokenOrReference requestedSecurityToken = null;
+    protected SecurityTokenOrReference requestedProofToken = null;
+
+    public RequestSecurityTokenResponse(Document doc) {
+        super(doc);
+    }
+
+    public RequestSecurityTokenResponse(Document doc, SecurityTokenOrReference requestedSecurityToken) {
+        super(doc);
+        this.requestedSecurityToken = requestedSecurityToken;
+    }
+
+    /**
+     * Constructs a RequestSecurityToken object from an existing element.
+     *
+     * @param element
+     */
+    public RequestSecurityTokenResponse(Element element) throws ElementParsingException {
+        super(element);
+        initialize();
+    }
+
+    public RequestSecurityTokenResponse(Element element, Document document) throws ElementParsingException {
+        super(element, document);
+        initialize();
+    }
+
+    private void initialize() throws ElementParsingException {
+        ArrayList elements = (ArrayList) customElements.clone();
+        customElements.clear();
+
+        for (int i = 0; i < elements.size(); i++) {
+            Element currentNode = (Element) elements.get(i);
+
+            if (!TrustConstants.WST_NS.equals(currentNode.getNamespaceURI())) {
+                addCustomElement(currentNode);
+                continue;
+            } else if (currentNode.getLocalName().equals(TrustConstants.REQUESTED_TOKEN)) {
+                Element elem = getFirstNonBlankChildAsElement(currentNode);
+                if (elem != null)
+                    setRequestedSecurityToken(new SecurityTokenOrReference(elem, doc));
+            } else if (currentNode.getLocalName().equals(TrustConstants.REQUESTED_PROOF)) {
+                Element elem = getFirstNonBlankChildAsElement(currentNode);
+                if (elem != null)
+                    setRequestedProofToken(new SecurityTokenOrReference(elem, doc));
+            } else
+                addCustomElement(currentNode);
+        }
+    }
+
+    public SecurityTokenOrReference getRequestedSecurityToken() {
+        return requestedSecurityToken;
+    }
+
+    public void setRequestedSecurityToken(SecurityTokenOrReference requestedToken) {
+        this.requestedSecurityToken = requestedToken;
+    }
+
+    public SecurityTokenOrReference getRequestedProofToken() {
+        return requestedProofToken;
+    }
+
+    public void setRequestedProofToken(SecurityTokenOrReference requestedProofToken) {
+        this.requestedProofToken = requestedProofToken;
+    }
+
+    public Element getElement() throws TrustException {
+        Element wstElement = getElement(TrustConstants.WST_PREFIX + TrustConstants.RESPONSE_TAG);
+
+        if ((requestedSecurityToken == null) && (requestedProofToken == null))
+            throw new NoTokenInResponse("Either a RequestedSecurityToken or a RequestedProofToken is required. Both cannot be null.");
+        else if (requestedSecurityToken != null)
+            wstElement.appendChild(createTokenOrReferenceElement(TrustConstants.WST_PREFIX + TrustConstants.REQUESTED_TOKEN,
+                    requestedSecurityToken));
+        else if (requestedProofToken != null)
+            wstElement.appendChild(createTokenOrReferenceElement(TrustConstants.WST_PREFIX + TrustConstants.REQUESTED_PROOF,
+                    requestedSecurityToken));
+
+        return wstElement;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/SecurityTokenMessage.java b/src/org/apache/ws/sandbox/security/trust2/SecurityTokenMessage.java
new file mode 100644
index 0000000..43db9ff
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/SecurityTokenMessage.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.sandbox.security.trust2.exception.ElementParsingException;
+import org.apache.ws.sandbox.security.trust2.exception.EmptyTokenOrReference;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.apache.axis.utils.DOM2Writer;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSSConfig;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A base class for WS-Trust messages such as <RequestSecurityToken> and <RequestSecurityTokenResponse>.
+ */
+public abstract class SecurityTokenMessage {
+
+    protected URI context = null;
+    protected URI tokenType = null;
+    protected URI keyType;
+
+    protected int keySize;
+    protected URI signatureAlgorithm;
+    protected SecurityTokenOrReference encryption;
+    protected SecurityTokenOrReference proofEncryption;
+    protected Lifetime lifetime = null;
+
+    protected ArrayList customElements = new ArrayList();
+
+    protected Element element;
+    protected Document doc;
+
+    /**
+     * Constructs a SecurityTokenMessage object from an existing element.
+     *
+     * @param element
+     */
+    public SecurityTokenMessage(Element element) throws ElementParsingException {
+        if (element != null) {
+            this.doc = element.getOwnerDocument();
+            initialize(element);
+        }
+    }
+
+    public SecurityTokenMessage(Element element, Document doc) throws ElementParsingException {
+        if (element != null) {
+            this.doc = doc;
+            initialize(element);
+        }
+    }
+
+    private void initialize(Element element) throws ElementParsingException {
+        try {
+            Attr context = element.getAttributeNodeNS(TrustConstants.WST_NS, TrustConstants.CONTEXT_ATTR);
+
+            if (context != null)
+                setContext(new URI(context.getValue()));
+
+            NodeList childNodes = element.getChildNodes();
+            if (childNodes != null) {
+                for (int i = 0; i < childNodes.getLength(); i++) {
+                    Node currentNode = childNodes.item(i);
+                    if (!TrustConstants.WST_NS.equals(currentNode.getNamespaceURI())) {
+                        if (currentNode instanceof Element)
+                            addCustomElement((Element) currentNode);
+                        continue;
+                    } else if (currentNode.getLocalName().equals(TrustConstants.TOKEN_TYPE)) {
+                        String textContent = getTextContent(currentNode);
+                        if (textContent != null && !textContent.equals(""))
+                            setTokenType(new URI(textContent));
+                    } else if (currentNode.getLocalName().equals(TrustConstants.LIFETIME) ||
+                            (TrustConstants.MS_COMPATIBLE_LIFETIMES && currentNode.getLocalName().equals(TrustConstants.LIFETIME_MS))) {
+
+                        lifetime = new Lifetime(WSSConfig.getDefaultWSConfig(), doc, (Element) currentNode);
+                    } else {
+                        if (currentNode instanceof Element)
+                            addCustomElement((Element) currentNode);
+                    }
+                }
+            }
+        } catch (URISyntaxException e) {
+            throw new ElementParsingException("URISyntaxException while creating SecurityTokenMessage from XML element: " + e.getMessage());
+        } catch (WSSecurityException e) {
+            throw new ElementParsingException("WSSecurityException while creating SecurityTokenMessage from XML element: " + e.getMessage());
+        }
+    }
+
+    public SecurityTokenMessage(Document doc) {
+        this.doc = doc;
+    }
+
+    public void setDocument(Document doc) {
+        this.doc = doc;
+    }
+
+    public Document getDocument() {
+        return doc;
+    }
+
+    public void setContext(URI context) {
+        this.context = context;
+    }
+
+    public URI getContext() {
+        return context;
+    }
+
+    public void setTokenType(URI tokenType) {
+        this.tokenType = tokenType;
+    }
+
+    public URI getTokenType() {
+        return tokenType;
+    }
+
+    public void addCustomElement(Element element) {
+        customElements.add(element);
+    }
+
+    public Element addCustomElement(String tagName) {
+        Element element = doc.createElement(tagName);
+        addCustomElement(element);
+        return element;
+    }
+
+    public Element addCustomElementNS(String namespaceUri, String qualifiedName) {
+        Element element = doc.createElementNS(namespaceUri, qualifiedName);
+        addCustomElement(element);
+        return element;
+    }
+
+    public List getCustomElements() {
+        return customElements;
+    }
+
+    public Element getCustomElement(String namespaceUri, String localName) {
+        Element currentElement;
+        for (Iterator itr = customElements.iterator(); itr.hasNext();) {
+            currentElement = (Element) itr.next();
+            String elementNs = currentElement.getNamespaceURI();
+            if ((namespaceUri == null && elementNs == null) || (namespaceUri != null && namespaceUri.equals(elementNs))) {
+                String elementLocalName = currentElement.getLocalName();
+                if ((localName == null && elementLocalName == null) || (localName != null && localName.equals(elementLocalName)))
+                    return currentElement;
+            }
+        }
+        return null;
+    }
+
+    public void setLifetime(Lifetime lifetime) {
+        this.lifetime = lifetime;
+    }
+
+    public Lifetime getLifetime() {
+        return lifetime;
+    }
+
+    public abstract Element getElement() throws TrustException;
+
+    protected Element getElement(String tagName) throws TrustException {
+        element = doc.createElementNS(TrustConstants.WST_NS, tagName);
+        if (context != null) {
+            element.setAttributeNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.CONTEXT_ATTR, context.toString());
+        }
+
+        if (tokenType != null) {
+            Element tokenTypeElement = doc.createElementNS(TrustConstants.WST_NS, TrustConstants.WST_PREFIX + TrustConstants.TOKEN_TYPE);
+            setTextContent(tokenTypeElement, tokenType.toString());
+            element.appendChild(tokenTypeElement);
+        }
+
+        for (Iterator itr = customElements.iterator(); itr.hasNext();) {
+            element.appendChild((Element) itr.next());
+        }
+
+        if (lifetime != null) {
+            element.appendChild(lifetime.getElement());
+        }
+
+        return element;
+    }
+
+    protected Element createTokenOrReferenceElement(String enclosingTagName, SecurityTokenOrReference token) throws TrustException {
+        Element element = doc.createElementNS(TrustConstants.WST_NS, enclosingTagName);
+        Element tokenElement = token.getElement();
+        if (tokenElement == null)
+            throw new EmptyTokenOrReference("SecurityTokenOrReference specified does not contain " +
+                    "a security token element or reference element.");
+        element.appendChild(tokenElement);
+        return element;
+    }
+
+    /**
+     * Adds a text child node to the given element.
+     *
+     * @param element The element to add text to
+     * @param string  The text string to add
+     */
+    protected void setTextContent(Element element, String string) {
+        Node textNode = doc.createTextNode(string);
+        element.appendChild(textNode);
+    }
+
+    protected String getTextContent(Node currentNode) {
+        NodeList nodes = currentNode.getChildNodes();
+        for (int j = 0; j < nodes.getLength(); j++) {
+            if (nodes.item(j).getNodeValue() != null)
+                return nodes.item(j).getNodeValue();
+        }
+        return null;
+    }
+
+    protected Element getFirstNonBlankChildAsElement(Node currentNode) {
+        NodeList nodes = currentNode.getChildNodes();
+        for (int j = 0; j < nodes.getLength(); j++) {
+            if (nodes.item(j).getLocalName() != null)
+                return (Element) nodes.item(j);
+        }
+        return null;
+    }
+
+    public String toString() {
+        try {
+            return DOM2Writer.nodeToString(getElement(), true);
+        } catch (TrustException e) {
+            return "TrustException when trying to convert to String: " + e.getMessage();
+        }
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/SecurityTokenOrReference.java b/src/org/apache/ws/sandbox/security/trust2/SecurityTokenOrReference.java
new file mode 100644
index 0000000..782610e
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/SecurityTokenOrReference.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.sandbox.security.trust2.exception.ElementParsingException;
+import org.apache.ws.sandbox.security.trust2.exception.InvalidSecurityTokenReference;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A class to hold either a security token of some kind (UsernameToken, BinarySecurityToken, etc.)
+ *         or a SecurityTokenReference.
+ */
+public class SecurityTokenOrReference {
+
+    protected Document doc = null;
+
+    protected SecurityTokenReference reference = null;
+    protected UsernameToken usernameToken = null;
+    protected BinarySecurity binarySecurityToken = null;
+
+    protected boolean isReference;
+
+    public boolean isReference() {
+        return reference != null;
+    }
+
+    public boolean isToken() {
+        return reference == null;
+    }
+
+    public SecurityTokenOrReference(Element element) throws ElementParsingException {
+
+        QName el = new QName(element.getNamespaceURI(), element.getLocalName());
+        WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+        try {
+            if (el.equals(SecurityTokenReference.SECURITY_TOKEN_REFERENCE))
+                this.reference = new SecurityTokenReference(element);
+            if (el.equals(UsernameToken.TOKEN))
+                this.usernameToken = new UsernameToken(element);
+            if (el.equals(BinarySecurity.TOKEN_BST))
+                this.binarySecurityToken = new BinarySecurity(element);
+            doc = element.getOwnerDocument();
+        } catch (WSSecurityException e) {
+            throw new ElementParsingException("WSSecurityException while trying to create a SecurityTokenOrReference object from an XML Element: "
+                    + e.getMessage());
+        }
+    }
+
+    public SecurityTokenOrReference(Element element, Document doc) throws ElementParsingException {
+        this(element);
+        this.doc = doc;
+    }
+
+    public SecurityTokenOrReference(SecurityTokenReference reference) {
+        this.reference = reference;
+    }
+
+    public SecurityTokenOrReference(UsernameToken securityToken) {
+        this.usernameToken = securityToken;
+    }
+
+    public SecurityTokenOrReference(BinarySecurity securityToken) {
+        this.binarySecurityToken = securityToken;
+    }
+
+    public void setDocument(Document doc) {
+        this.doc = doc;
+    }
+
+    public Element getElement() {
+        if (reference != null)
+            return reference.getElement();
+        else
+            return getTokenElement();
+    }
+
+    private Element getTokenElement() {
+        if (usernameToken != null)
+            return usernameToken.getElement();
+        if (binarySecurityToken != null)
+            return binarySecurityToken.getElement();
+        return null;
+    }
+
+    public Object getTokenOrReference() throws TrustException {
+        if (reference != null)
+            return reference;
+        return resolveToken();
+    }
+
+    public Object resolveToken() throws TrustException {
+        if (usernameToken != null)
+            return usernameToken;
+        if (binarySecurityToken != null)
+            return binarySecurityToken;
+        if (reference != null) {
+            try {
+                Element tokenElement = reference.getTokenElement(doc, null);
+                if (tokenElement != null) {
+                    QName el = new QName(tokenElement.getNamespaceURI(), tokenElement.getLocalName());
+                    try {
+                        WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+                        if (el.equals(UsernameToken.TOKEN))
+                            return new UsernameToken(tokenElement);
+                        if (el.equals(BinarySecurity.TOKEN_BST))
+                            return new BinarySecurity(tokenElement);
+                    } catch (WSSecurityException e) {
+                        throw new ElementParsingException("WSSecurityException while trying to create a SecurityToken object from a SecurityTokenReference: "
+                                + e.getMessage());
+                    }
+                }
+            } catch (WSSecurityException e) {
+                throw new InvalidSecurityTokenReference("WSSecurityException while trying to dereference a <SecurityTokenReference>: " + e.getMessage());
+            }
+        }
+        return null;
+    }
+
+    public SecurityTokenReference getReference() {
+        return reference;
+    }
+
+    public UsernameToken getUsernameToken() {
+        return usernameToken;
+    }
+
+    public BinarySecurity getBinarySecurity() {
+        return binarySecurityToken;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/TokenTypes.java b/src/org/apache/ws/sandbox/security/trust2/TokenTypes.java
new file mode 100644
index 0000000..57f71d7
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/TokenTypes.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.message.token.PKIPathSecurity;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A set of URI constants representing different token types defined by the WS-Security TC. These are typically used
+ *         in the WS-Trust <TokenType> element.
+ */
+public abstract class TokenTypes {
+    public static URI USERNAME;
+
+    private static final String x509prefix = WSConstants.X509TOKEN_NS;
+
+    public static URI X509;
+    public static URI X509PKIPATH;
+    public static URI PKCS7;
+
+    static {
+        try {
+            USERNAME = new URI(WSConstants.USERNAMETOKEN_NS + "#" + WSConstants.USERNAME_TOKEN_LN);
+            X509 = new URI(X509Security.getType());
+            X509PKIPATH = new URI(PKIPathSecurity.getType());
+            PKCS7 = new URI(x509prefix + "#PKCS7");
+        } catch (URISyntaxException e) {
+        }
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/TrustConstants.java b/src/org/apache/ws/sandbox/security/trust2/TrustConstants.java
new file mode 100644
index 0000000..3cbcc05
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/TrustConstants.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import javax.xml.namespace.QName;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         WS-Trust constants.
+ */
+public abstract class TrustConstants {
+
+    private static final String NS_YEAR_PREFIX = "http://schemas.xmlsoap.org/ws/2004/04/";
+    public static final String WST_NS = NS_YEAR_PREFIX + "trust";
+    public static final String WST_PREFIX = "wst:";
+
+    public static final String REQUEST_TAG = "RequestSecurityToken";
+    public static final QName REQUEST_NAME = new QName(WST_NS, REQUEST_TAG, WST_PREFIX);
+
+    public static final String CONTEXT_ATTR = "Context";
+    public static final String TOKEN_TYPE = "TokenType";
+    public static final String REQUEST_TYPE = "RequestType";
+    public static final String BASE = "Base";
+    public static final String SUPPORTING = "Supporting";
+    public static final String LIFETIME = "Lifetime";
+    public static final String LIFETIME_MS = "LifeTime";
+
+    public static final boolean MS_COMPATIBLE_LIFETIMES = true;
+
+    public static final String RESPONSE_TAG = "RequestSecurityTokenResponse";
+    public static final QName RESPONSE_NAME = new QName(WST_NS, RESPONSE_TAG, WST_PREFIX);
+
+    public static final String REQUESTED_TOKEN = "RequestedSecurityToken";
+    public static final String REQUESTED_PROOF = "RequestedProofToken";
+
+    public static final String WSA_NS = "http://schemas.xmlsoap.org/ws/2004/03/addressing";
+    public static final String WSA_PREFIX = "wsa:";
+    public static final String ACTION_TAG = "Action";
+
+    private static final String SECURITY_TRUST_PREFIX = NS_YEAR_PREFIX + "security/trust/";
+
+    public static URI REQUEST_ISSUE;
+    public static URI REQUEST_RENEW;
+    public static URI REQUEST_VALIDATE;
+
+    private static final String ACTION_REQUEST_PREFIX = SECURITY_TRUST_PREFIX + "RST/";
+
+    public static URI ACTION_REQUEST_ISSUE;
+    public static URI ACTION_REQUEST_RENEW;
+    public static URI ACTION_REQUEST_VALIDATE;
+
+    private static final String ACTION_RESPONSE_PREFIX = SECURITY_TRUST_PREFIX + "RSTR/";
+
+    public static URI ACTION_RESPONSE_ISSUE;
+    public static URI ACTION_RESPONSE_RENEW;
+    public static URI ACTION_RESPONSE_VALIDATE;
+
+    static {
+        try {
+            REQUEST_ISSUE = new URI(SECURITY_TRUST_PREFIX + "Issue");
+            REQUEST_RENEW = new URI(SECURITY_TRUST_PREFIX + "Renew");
+            REQUEST_VALIDATE = new URI(SECURITY_TRUST_PREFIX + "Validate");
+
+            ACTION_REQUEST_ISSUE = new URI(ACTION_REQUEST_PREFIX + "Issue");
+            ACTION_REQUEST_RENEW = new URI(ACTION_REQUEST_PREFIX + "Renew");
+            ACTION_REQUEST_VALIDATE = new URI(ACTION_REQUEST_PREFIX + "Validate");
+
+            ACTION_RESPONSE_ISSUE = new URI(ACTION_RESPONSE_PREFIX + "Issue");
+            ACTION_RESPONSE_RENEW = new URI(ACTION_RESPONSE_PREFIX + "Renew");
+            ACTION_RESPONSE_VALIDATE = new URI(ACTION_RESPONSE_PREFIX + "Validate");
+        } catch (URISyntaxException e) {
+        }
+    }
+
+    public static URI getActionRequest(URI requestType) {
+        if (REQUEST_ISSUE.equals(requestType))
+            return ACTION_REQUEST_ISSUE;
+        if (REQUEST_ISSUE.equals(requestType))
+            return ACTION_REQUEST_RENEW;
+        if (REQUEST_ISSUE.equals(requestType))
+            return ACTION_REQUEST_VALIDATE;
+        return requestType;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/WSAddTokenRequest.java b/src/org/apache/ws/sandbox/security/trust2/WSAddTokenRequest.java
new file mode 100644
index 0000000..b049ca1
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/WSAddTokenRequest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2;
+
+import org.apache.ws.sandbox.security.trust2.exception.NoRequestType;
+import org.apache.ws.sandbox.security.trust2.exception.NoSoapBody;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import java.net.URI;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A class for adding a WS-Trust RequestSecurityToken element to a SOAP envelope (an XML document).
+ */
+public class WSAddTokenRequest {
+
+    private URI action = null;
+    private RequestSecurityToken tokenRequest;
+
+    public WSAddTokenRequest(RequestSecurityToken tokenRequest) {
+        this.tokenRequest = tokenRequest;
+    }
+
+    /**
+     * Adds the standard Action element corresponding to the RequestType specified in the RequestSecurityToken message being used.
+     * If the request type is non-standard (not Issue, Renew, Validate), the Action URI added will be the same as the RequestType URI.
+     *
+     * @throws NoRequestType
+     */
+    public void addAction() throws NoRequestType {
+        action = TrustConstants.getActionRequest(tokenRequest.getRequestType());
+        if (action == null) {
+            throw new NoRequestType("Cannot generate standard action element, no requestType specified.");
+        }
+    }
+
+    /**
+     * Adds a custom Action element to the SOAP header. See WS-Addressing specs for more details.
+     *
+     * @param action The action URI to add.
+     */
+    public void addAction(URI action) {
+        this.action = action;
+    }
+
+    /**
+     * Adds a new <code>RequestSecurityToken</code> to a soap envelope.
+     * <p/>
+     *
+     * @param doc The SOAP enevlope as W3C document
+     * @return Document with RequestSecurityToken added
+     * @throws DOMException NoRequestType NoSoapBody
+     */
+    public Document build(Document doc) throws DOMException, TrustException {
+        SOAPConstants soapConsts = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+
+        if (action != null) {
+            Element envelope = doc.getDocumentElement();
+            Element soapHeader = (Element) WSSecurityUtil.getDirectChild(doc.getFirstChild(), soapConsts.getHeaderQName().getLocalPart(),
+                    soapConsts.getEnvelopeURI());
+
+            if (soapHeader == null) {
+                soapHeader = createElementInSameNamespace(envelope, soapConsts.getHeaderQName().getLocalPart());
+                soapHeader = WSSecurityUtil.prependChildElement(doc, envelope, soapHeader, true);
+            }
+
+            Element actionElement = doc.createElementNS(TrustConstants.WSA_NS, TrustConstants.WST_PREFIX + TrustConstants.ACTION_TAG);
+            Node actionContent = doc.createTextNode(action.toString());
+            actionElement.appendChild(actionContent);
+            soapHeader.appendChild(actionElement);
+        }
+        Element soapBody = WSSecurityUtil.findBodyElement(doc, soapConsts);
+        if (soapBody == null) {
+            throw new NoSoapBody("A SOAP Body element is needed to insert the <RequestSecurityToken>.");
+        }
+
+        setWsuId(soapBody);
+        if (tokenRequest != null)
+            soapBody.appendChild(tokenRequest.getElement());
+        return doc;
+    }
+
+    /**
+     * create a new element in the same namespace
+     * <p/>
+     *
+     * @param parent
+     * @param localName
+     * @return
+     */
+    private static Element createElementInSameNamespace(Element parent, String localName) {
+        String prefix = parent.getPrefix();
+        if (prefix == null) {
+            prefix = "";
+        }
+        String qName = prefix + ":" + localName;
+        String nsUri = parent.getNamespaceURI();
+        return parent.getOwnerDocument().createElementNS(nsUri, qName);
+    }
+
+    private String setWsuId(Element bodyElement) {
+        String id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id");
+        if ((id == null) || (id.length() == 0)) {
+            id = "id-" + Integer.toString(bodyElement.hashCode());
+            String prefix = WSSecurityUtil.setNamespace(bodyElement, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+            bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+        }
+        return id;
+    }
+
+    public static void main(String[] args) throws Exception {
+        SOAPEnvelope env = new SOAPEnvelope();
+        Document doc = env.getAsDocument();
+        WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+
+        RequestSecurityToken tokenRequest = new RequestSecurityToken(doc, TrustConstants.REQUEST_ISSUE);
+
+        tokenRequest.setContext(new URI("http://context.context"));
+        tokenRequest.setTokenType(TokenTypes.X509);
+
+        UsernameToken userToken = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        userToken.setName("bob");
+        userToken.setPassword("bobspass");
+        tokenRequest.setBase(new SecurityTokenOrReference(userToken));
+
+        UsernameToken user2Token = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        user2Token.setName("joe");
+        user2Token.setPassword("bobspass");
+        tokenRequest.addSupporting(new SecurityTokenOrReference(user2Token));
+
+        UsernameToken user3Token = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc);
+        user3Token.setName("mike");
+        user3Token.setPassword("bobspass");
+        tokenRequest.addSupporting(new SecurityTokenOrReference(user3Token));
+
+        WSAddTokenRequest builder = new WSAddTokenRequest(tokenRequest);
+        builder.addAction();
+        doc = builder.build(doc);
+        /*
+        WSSignEnvelope builder = new WSSignEnvelope();
+        builder.setUserInfo(credName, password);
+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        doc = builder.build(env.getAsDocument(), CryptoFactory.getInstance(cryptoPropFile));
+*/
+										
+        System.out.println("\n============= Request ==============");
+        System.out.println(org.apache.axis.utils.XMLUtils.DocumentToString(doc));
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/ElementParsingException.java b/src/org/apache/ws/sandbox/security/trust2/exception/ElementParsingException.java
new file mode 100644
index 0000000..32fbb42
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/ElementParsingException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For when there is a problem trying to create a WS-Trust object from a XML Element.
+ */
+public class ElementParsingException extends TrustException {
+
+    public ElementParsingException(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/EmptyTokenOrReference.java b/src/org/apache/ws/sandbox/security/trust2/exception/EmptyTokenOrReference.java
new file mode 100644
index 0000000..1f10450
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/EmptyTokenOrReference.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         To change the template for this generated type comment go to
+ *         Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+public class EmptyTokenOrReference extends TrustException {
+
+    public EmptyTokenOrReference(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/InvalidSecurityTokenReference.java b/src/org/apache/ws/sandbox/security/trust2/exception/InvalidSecurityTokenReference.java
new file mode 100644
index 0000000..746d33b
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/InvalidSecurityTokenReference.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For when a SecurityTokenReference is invalid or points to nothing.
+ */
+public class InvalidSecurityTokenReference extends TrustException {
+
+    public InvalidSecurityTokenReference(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/NoRequestType.java b/src/org/apache/ws/sandbox/security/trust2/exception/NoRequestType.java
new file mode 100644
index 0000000..f596bec
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/NoRequestType.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         An exception to indicate when a RequestType has not been specified (a violation of the WS-Trust specs).
+ */
+public class NoRequestType extends TrustException {
+
+    public NoRequestType(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/NoSoapBody.java b/src/org/apache/ws/sandbox/security/trust2/exception/NoSoapBody.java
new file mode 100644
index 0000000..57fb56c
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/NoSoapBody.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         An exception to indicate that a document lacking a SOAP body element is trying to get used.
+ */
+public class NoSoapBody extends TrustException {
+    public NoSoapBody(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/NoTokenInResponse.java b/src/org/apache/ws/sandbox/security/trust2/exception/NoTokenInResponse.java
new file mode 100644
index 0000000..0a6b57d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/NoTokenInResponse.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         An exception to indicate that a <RequestSecurityTokenResponse> message does not contain either a RequestedSecurityToken
+ *         or RequestedProofToken element. WS-Trust requires at least one of the two.
+ */
+public class NoTokenInResponse extends TrustException {
+    public NoTokenInResponse(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/NonStandardRequestType.java b/src/org/apache/ws/sandbox/security/trust2/exception/NonStandardRequestType.java
new file mode 100644
index 0000000..5706654
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/NonStandardRequestType.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         An exception to indicate that a custom request type was used where standard type (Issue, Renew, Validate) was expected.
+ */
+public class NonStandardRequestType extends TrustException {
+    public NonStandardRequestType(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/exception/TrustException.java b/src/org/apache/ws/sandbox/security/trust2/exception/TrustException.java
new file mode 100644
index 0000000..2fa03f8
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/exception/TrustException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.exception;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         A base class for all the WS-Trust related exceptions.
+ */
+public class TrustException extends Exception {
+    public TrustException(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/BasicSerializerFactory.java b/src/org/apache/ws/sandbox/security/trust2/serialization/BasicSerializerFactory.java
new file mode 100644
index 0000000..b6d3e36
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/BasicSerializerFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.axis.Constants;
+import org.apache.axis.encoding.DeserializerFactory;
+import org.apache.axis.encoding.SerializerFactory;
+
+import javax.xml.rpc.encoding.Deserializer;
+import javax.xml.rpc.encoding.Serializer;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         An abstract base class for creating Axis-SAX serializers.
+ */
+public abstract class BasicSerializerFactory implements SerializerFactory, DeserializerFactory {
+    private Vector mechanisms;
+
+    public Iterator getSupportedMechanismTypes() {
+        if (mechanisms == null) {
+            mechanisms = new Vector();
+            mechanisms.add(Constants.AXIS_SAX);
+        }
+        return mechanisms.iterator();
+    }
+
+    public Serializer getSerializerAs(String arg0) {
+        return null;
+    }
+
+    public Deserializer getDeserializerAs(String arg0) {
+        return null;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializer.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializer.java
new file mode 100644
index 0000000..e465906
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializer.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.axis.encoding.DeserializationContext;
+import org.apache.axis.encoding.DeserializerImpl;
+import org.apache.ws.sandbox.security.trust2.RequestSecurityToken;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For deserializing RequestSecurityToken objects/elements.
+ */
+public class RSTDeserializer extends DeserializerImpl {
+    public static final QName myTypeQName = TrustConstants.REQUEST_NAME;
+
+    private RequestSecurityToken tokenRequest;
+
+    public RSTDeserializer() {
+    }
+
+    public void onStartElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context)
+            throws SAXException {
+
+        try {
+            tokenRequest = new RequestSecurityToken(context.getCurElement().getAsDOM(), context.getEnvelope().getAsDocument());
+            value = tokenRequest;
+        } catch (Exception e) {
+            throw new SAXException("Exception while processing RequestSecurityToken startElement: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializerFactory.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializerFactory.java
new file mode 100644
index 0000000..71dcf9b
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTDeserializerFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import javax.xml.rpc.encoding.Deserializer;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For creating RSTDeserializers.
+ */
+public class RSTDeserializerFactory extends BasicSerializerFactory {
+    public Deserializer getDeserializerAs(String arg0) {
+        return new RSTDeserializer();
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializer.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializer.java
new file mode 100644
index 0000000..2f19c42
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializer.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.apache.axis.encoding.DeserializationContext;
+import org.apache.axis.encoding.DeserializerImpl;
+import org.apache.axis.message.SOAPHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For deserializing RequestSecurityTokenResponse objects/elements.
+ */
+public class RSTResponseDeserializer extends DeserializerImpl {
+    public static final QName myTypeQName = TrustConstants.RESPONSE_NAME;
+
+    private RequestSecurityTokenResponse tokenResponse;
+
+    public RSTResponseDeserializer() {
+    }
+
+    public SOAPHandler onStartChild(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context)
+            throws SAXException {
+
+        try {
+            tokenResponse = new RequestSecurityTokenResponse(context.getCurElement().getAsDOM(), context.getEnvelope().getAsDocument());
+            value = tokenResponse;
+        } catch (Exception e) {
+            throw new SAXException("Exception while processing RequestSecurityTokenResponse startElement: " + e.getMessage());
+        }
+
+        return null;
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializerFactory.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializerFactory.java
new file mode 100644
index 0000000..f48341d
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseDeserializerFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import javax.xml.rpc.encoding.Deserializer;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For creating RSTResponseDeserializers.
+ */
+public class RSTResponseDeserializerFactory extends BasicSerializerFactory {
+    public Deserializer getDeserializerAs(String arg0) {
+        return new RSTResponseDeserializer();
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializer.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializer.java
new file mode 100644
index 0000000..d473d99
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializer.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse;
+import org.apache.axis.encoding.SerializationContext;
+import org.xml.sax.Attributes;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For serializing RequestSecurityTokenResponse objects into their XML representation.
+ */
+public class RSTResponseSerializer extends SecurityTokenMessageSerializer {
+
+    /**
+     * Serialize an element named name, with the indicated attributes
+     * and value.
+     *
+     * @param name       is the element name
+     * @param attributes are the attributes...serialize is free to add more.
+     * @param value      is the value
+     * @param context    is the SerializationContext
+     */
+    public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException {
+        if (!(value instanceof RequestSecurityTokenResponse))
+            throw new IOException("Can't serialize a " + value.getClass().getName() + " with a RSTResponseSerializer.");
+
+        super.serialize(name, attributes, value, context);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializerFactory.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializerFactory.java
new file mode 100644
index 0000000..59be30f
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTResponseSerializerFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import javax.xml.rpc.encoding.Serializer;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For creating RSTResponseSerializers.
+ */
+public class RSTResponseSerializerFactory extends BasicSerializerFactory {
+
+    public Serializer getSerializerAs(String arg0) {
+        return new RSTResponseSerializer();
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializer.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializer.java
new file mode 100644
index 0000000..3f7d60e
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializer.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.ws.sandbox.security.trust2.RequestSecurityToken;
+import org.apache.axis.encoding.SerializationContext;
+import org.xml.sax.Attributes;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For serializing RequestSecurityToken objects into their XML representation.
+ */
+public class RSTSerializer extends SecurityTokenMessageSerializer {
+
+    /**
+     * Serialize an element named name, with the indicated attributes
+     * and value.
+     *
+     * @param name       is the element name
+     * @param attributes are the attributes...serialize is free to add more.
+     * @param value      is the value
+     * @param context    is the SerializationContext
+     */
+    public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException {
+        if (!(value instanceof RequestSecurityToken))
+            throw new IOException("Can't serialize a " + value.getClass().getName() + " with a RSTSerializer.");
+
+        super.serialize(name, attributes, value, context);
+    }
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializerFactory.java b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializerFactory.java
new file mode 100644
index 0000000..c5c790a
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/RSTSerializerFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import javax.xml.rpc.encoding.Serializer;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For creating RSTSerializers.
+ */
+public class RSTSerializerFactory extends BasicSerializerFactory {
+
+    public Serializer getSerializerAs(String arg0) {
+        return new RSTSerializer();
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/SecurityTokenMessageSerializer.java b/src/org/apache/ws/sandbox/security/trust2/serialization/SecurityTokenMessageSerializer.java
new file mode 100644
index 0000000..4bdb38e
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/SecurityTokenMessageSerializer.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.ws.sandbox.security.trust2.SecurityTokenMessage;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.apache.ws.sandbox.security.trust2.exception.TrustException;
+import org.apache.axis.Constants;
+import org.apache.axis.encoding.SerializationContext;
+import org.apache.axis.encoding.Serializer;
+import org.apache.axis.wsdl.fromJava.Types;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+
+/**
+ * @author ddelvecc
+ *         <p/>
+ *         For serializing any SecurityTokenMessage objects into their XML representation.
+ */
+public abstract class SecurityTokenMessageSerializer implements Serializer {
+
+    /**
+     * Serialize an element named name, with the indicated attributes
+     * and value.
+     *
+     * @param name       is the element name
+     * @param attributes are the attributes...serialize is free to add more.
+     * @param value      is the value
+     * @param context    is the SerializationContext
+     */
+    public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException {
+        if (!(value instanceof SecurityTokenMessage))
+            throw new IOException("Can't serialize a " + value.getClass().getName() + " with a SecurityTokenMessageSerializer.");
+
+        context.setPretty(false);
+
+        SecurityTokenMessage tokenRequest = (SecurityTokenMessage) value;
+        try {
+
+            Element element = tokenRequest.getElement();
+            if (name.equals(new QName(element.getNamespaceURI(), element.getLocalName()))) {
+                AttributesImpl attrs = null;
+                if (attributes != null)
+                    attrs = new AttributesImpl(attributes);
+                else
+                    attrs = new AttributesImpl();
+                Attr ctxt = element.getAttributeNodeNS(TrustConstants.WST_NS, TrustConstants.CONTEXT_ATTR);
+                if (ctxt != null)
+                    attrs.addAttribute(ctxt.getNamespaceURI(), ctxt.getLocalName(), ctxt.getName(), "CDATA", ctxt.getValue());
+
+                context.startElement(name, attrs);
+                NodeList children = element.getChildNodes();
+                if (children != null) {
+                    for (int i = 0; i < children.getLength(); i++)
+                        context.writeDOMElement((Element) children.item(i));
+                }
+            } else {
+                context.startElement(name, attributes);
+                context.writeDOMElement(element);
+            }
+
+            context.endElement();
+        } catch (TrustException e) {
+            throw new IOException("TrustException during SecurityTokenMessage serialization: " + e.getMessage());
+        } catch (Exception e) {
+            throw new IOException("Exception during SecurityTokenMessage serialization: " + e.getMessage());
+        }
+    }
+
+    public Element writeSchema(Class javaType, Types types) throws Exception {
+        return null;
+    }
+
+    public String getMechanismType() {
+        return Constants.AXIS_SAX;
+    }
+
+}
diff --git a/src/org/apache/ws/sandbox/security/trust2/serialization/TestSerialization.java b/src/org/apache/ws/sandbox/security/trust2/serialization/TestSerialization.java
new file mode 100644
index 0000000..897800e
--- /dev/null
+++ b/src/org/apache/ws/sandbox/security/trust2/serialization/TestSerialization.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.sandbox.security.trust2.serialization;
+
+import org.apache.ws.sandbox.security.trust2.RequestSecurityTokenResponse;
+import org.apache.ws.sandbox.security.trust2.SecurityTokenOrReference;
+import org.apache.ws.sandbox.security.trust2.TokenTypes;
+import org.apache.ws.sandbox.security.trust2.TrustConstants;
+import org.apache.axis.Constants;
+import org.apache.axis.MessageContext;
+import org.apache.axis.encoding.DeserializationContext;
+import org.apache.axis.encoding.SerializationContext;
+import org.apache.axis.encoding.TypeMapping;
+import org.apache.axis.encoding.TypeMappingRegistry;
+import org.apache.axis.message.RPCElement;
+import org.apache.axis.message.RPCParam;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.server.AxisServer;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.WSSConfig;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import java.io.FileReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+
+public class TestSerialization {
+
+    public static void main(String[] args) throws Exception {
+        MessageContext msgContext = new MessageContext(new AxisServer());
+        SOAPEnvelope msg = new SOAPEnvelope();
+        RPCParam arg1 = new RPCParam("urn:myNamespace", "testParam", "this is a string");
+        //QName dataQName = new QName("typeNS", "Data");
+
+        Document doc = msg.getAsDocument();
+
+        UsernameToken userToken = new UsernameToken(WSSConfig.getDefaultWSConfig().isPrecisionInMilliSeconds(),doc);
+        userToken.setName("bob");
+        userToken.setPassword("bobspass");
+
+        RequestSecurityTokenResponse tokenResponse = new RequestSecurityTokenResponse(doc, new SecurityTokenOrReference(userToken));
+        tokenResponse.setContext(new URI("http://context.context"));
+        tokenResponse.setTokenType(TokenTypes.USERNAME);
+		
+        /*
+        Data data = new Data();
+        Data data2 = new Data();
+        data.stringMember = "String member";
+        data.floatMember = new Float("1.23");
+        data.dataMember = data2;
+        
+        data2.stringMember = "another str member";
+        data2.floatMember = new Float("4.56");
+        data2.dataMember = null;  // "data;" for loop-test of multi-refs
+*/
+        RPCParam arg2 = new RPCParam("", "struct", tokenResponse);
+        RPCElement body = new RPCElement("urn:myNamespace", "method1", new Object[]{arg1, arg2});
+        msg.addBodyElement(body);
+
+        try {
+            Reader reader = null;
+
+            if (args.length == 0) {
+                Writer stringWriter = new StringWriter();
+                SerializationContext context = new SerializationContext(stringWriter, msgContext);
+
+                TypeMappingRegistry reg = context.getTypeMappingRegistry();
+                TypeMapping tm = (TypeMapping) reg.getTypeMapping(Constants.URI_SOAP11_ENC);
+                if (tm == null) {
+                    tm = (TypeMapping) reg.createTypeMapping();
+                    reg.register(Constants.URI_DEFAULT_SOAP_ENC, tm);
+                }
+                tm.register(RequestSecurityTokenResponse.class, TrustConstants.RESPONSE_NAME, new RSTResponseSerializerFactory(), new RSTResponseDeserializerFactory());
+
+                msg.output(context);
+
+                String msgString = stringWriter.toString();
+                System.out.println("Serialized msg:");
+                System.out.println(msgString);
+
+                System.out.println("-------");
+                System.out.println("Testing deserialization...");
+
+                reader = new StringReader(msgString);
+            } else {
+                reader = new FileReader(args[0]);
+            }
+
+            DeserializationContext dser = new DeserializationContext(new InputSource(reader), msgContext, org.apache.axis.Message.REQUEST);
+            dser.parse();
+            SOAPEnvelope env = dser.getEnvelope();
+            //System.out.println("********\n" + DOM2Writer.nodeToString(env, true) + "\n********");
+            
+            RPCElement rpcElem = (RPCElement) env.getFirstBody();
+            RPCParam struct = rpcElem.getParam("struct");
+            if (struct == null)
+                throw new Exception("No <struct> param");
+
+            if (!(struct.getObjectValue() instanceof RequestSecurityTokenResponse)) {
+                System.out.println("Not a RST object! ");
+                System.out.println(struct.getValue());
+                System.exit(1);
+            }
+
+            RequestSecurityTokenResponse val = (RequestSecurityTokenResponse) struct.getObjectValue();
+            if (val == null)
+                throw new Exception("No value for struct param");
+
+            System.out.println(val.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/org/apache/ws/security/SOAP11Constants.java b/src/org/apache/ws/security/SOAP11Constants.java
new file mode 100644
index 0000000..5930926
--- /dev/null
+++ b/src/org/apache/ws/security/SOAP11Constants.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import javax.xml.namespace.QName;
+
+/**
+ * SOAP 1.1 constants
+ *
+ * @author Glen Daniels (gdaniels@apache.org)
+ * @author Andras Avar (andras.avar@nokia.com)
+ */
+public class SOAP11Constants implements SOAPConstants {
+    private static QName headerQName = new QName(WSConstants.URI_SOAP11_ENV,
+            WSConstants.ELEM_HEADER);
+    private static QName bodyQName = new QName(WSConstants.URI_SOAP11_ENV,
+            WSConstants.ELEM_BODY);
+    private static QName roleQName = new QName(WSConstants.URI_SOAP11_ENV,
+            WSConstants.ATTR_ACTOR);
+
+    public String getEnvelopeURI() {
+        return WSConstants.URI_SOAP11_ENV;
+    }
+
+    public QName getHeaderQName() {
+        return headerQName;
+    }
+
+    public QName getBodyQName() {
+        return bodyQName;
+    }
+
+    /**
+     * Obtain the QName for the role attribute (actor/role)
+     */
+    public QName getRoleAttributeQName() {
+        return roleQName;
+    }
+
+    /**
+     * Obtain the "next" role/actor URI
+     */
+    public String getNextRoleURI() {
+        return WSConstants.URI_SOAP11_NEXT_ACTOR;
+    }
+
+    /**
+     * Obtain the Mustunderstand string
+     */
+    public String getMustunderstand() {
+        return "1";
+    }
+
+}
diff --git a/src/org/apache/ws/security/SOAP12Constants.java b/src/org/apache/ws/security/SOAP12Constants.java
new file mode 100644
index 0000000..cc4ea3b
--- /dev/null
+++ b/src/org/apache/ws/security/SOAP12Constants.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import javax.xml.namespace.QName;
+
+/**
+ * SOAP 1.2 constants
+ *
+ * @author Glen Daniels (gdaniels@apache.org)
+ * @author Andras Avar (andras.avar@nokia.com)
+ */
+public class SOAP12Constants implements SOAPConstants {
+    private static QName headerQName = new QName(WSConstants.URI_SOAP12_ENV,
+            WSConstants.ELEM_HEADER);
+    private static QName bodyQName = new QName(WSConstants.URI_SOAP12_ENV,
+            WSConstants.ELEM_BODY);
+    private static QName roleQName = new QName(WSConstants.URI_SOAP12_ENV,
+            WSConstants.ATTR_ROLE);
+    
+    // Public constants for SOAP 1.2
+    
+    /**
+     * MessageContext property name for webmethod
+     */
+    public static final String PROP_WEBMETHOD = "soap12.webmethod";
+
+    public String getEnvelopeURI() {
+        return WSConstants.URI_SOAP12_ENV;
+    }
+
+    public QName getHeaderQName() {
+        return headerQName;
+    }
+
+    public QName getBodyQName() {
+        return bodyQName;
+    }
+
+    /**
+     * Obtain the QName for the role attribute (actor/role)
+     */
+    public QName getRoleAttributeQName() {
+        return roleQName;
+    }
+
+    /**
+     * Obtain the "next" role/actor URI
+     */
+    public String getNextRoleURI() {
+        return WSConstants.URI_SOAP12_NEXT_ROLE;
+    }
+
+    /**
+     * Obtain the Mustunderstand string
+     */
+    public String getMustunderstand() {
+        return "true";
+    }
+
+}
diff --git a/src/org/apache/ws/security/SOAPConstants.java b/src/org/apache/ws/security/SOAPConstants.java
new file mode 100644
index 0000000..45c30cf
--- /dev/null
+++ b/src/org/apache/ws/security/SOAPConstants.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import javax.xml.namespace.QName;
+import java.io.Serializable;
+
+/**
+ * An interface definining SOAP constants.  This allows various parts of the
+ * engine to avoid hardcoding dependence on a particular SOAP version and its
+ * associated URIs, etc.
+ * <p/>
+ * This might be fleshed out later to encapsulate factories for behavioral
+ * objects which act differently depending on the SOAP version, but for now
+ * it just supplies common namespaces + QNames.
+ *
+ * @author Glen Daniels (gdaniels@apache.org)
+ * @author Andras Avar (andras.avar@nokia.com)
+ */
+public interface SOAPConstants extends Serializable {
+    /**
+     * SOAP 1.1 constants - thread-safe and shared
+     */
+    public SOAP11Constants SOAP11_CONSTANTS = new SOAP11Constants();
+    /**
+     * SOAP 1.2 constants - thread-safe and shared
+     */
+    public SOAP12Constants SOAP12_CONSTANTS = new SOAP12Constants();
+
+    /**
+     * Obtain the envelope namespace for this version of SOAP
+     */
+    public String getEnvelopeURI();
+
+    /**
+     * Obtain the QName for the Header element
+     */
+    public QName getHeaderQName();
+
+    /**
+     * Obtain the QName for the Body element
+     */
+    public QName getBodyQName();
+
+    /**
+     * Obtain the QName for the role attribute (actor/role)
+     */
+    public QName getRoleAttributeQName();
+
+    /**
+     * Obtain the "next" role/actor URI
+     */
+    public String getNextRoleURI();
+
+    /**
+     * Obtain the "next" role/actor URI
+     */
+    public String getMustunderstand();
+
+}
diff --git a/src/org/apache/ws/security/Todolist.java b/src/org/apache/ws/security/Todolist.java
new file mode 100644
index 0000000..a5a58e6
--- /dev/null
+++ b/src/org/apache/ws/security/Todolist.java
@@ -0,0 +1,32 @@
+/*
+ * Created on 17.03.2004
+ *
+ */
+package org.apache.ws.security;
+
+/**
+ * @author wdi
+ */
+public class Todolist {
+	/*
+	 * This is not really a java source but a todo list. Eclipse displays this
+	 * list automatically on the task list. Convenient.
+	 * 
+	 * Please fill in any new items that should be done. Rename the ToDo marker
+	 * to DONE if done, add your name, and some comments if necessary to keep
+	 * the list uptodate.
+	 * 
+	 * TODO: Clean up exception handling, remap to WSSecurityException, avoid
+	 * generic Exception.
+	 * 
+	 * TODO: make Cipher provider configurable
+	 * 
+	 * DONE: new function to perform Certificate handover from request to
+	 * response according to Kojira's explanation. Werner, checkin March, 24
+	 * 
+	 * TODO: Better texts for the Exception, see OASIS WSS specs for recommended
+	 * fault strings
+	 * 
+	 */
+
+}
diff --git a/src/org/apache/ws/security/WSConstants.java b/src/org/apache/ws/security/WSConstants.java
new file mode 100644
index 0000000..940c930
--- /dev/null
+++ b/src/org/apache/ws/security/WSConstants.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.utils.EncryptionConstants;
+
+/**
+ * Constants in WS-Security spec.
+ */
+public class WSConstants {
+    /*
+     * All the various string and keywords required.
+     * 
+     * At first the WSS namespaces as per WSS specifications
+     */
+    public static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
+    public static final String WSSE11_NS = "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd";
+    public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+    
+    /*
+     * The base UIRs for the various profiles.
+     */
+    public static final String SOAPMESSAGE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0";
+    public static final String SOAPMESSAGE_NS11 = "http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-soap-message-security-1.0";
+    public static final String USERNAMETOKEN_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0";
+    public static final String X509TOKEN_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0";
+    public static final String SAMLTOKEN_NS = "http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0";
+    /*
+     * The Element name (local name) of the security header
+     */
+    public static final String WSSE_LN = "Security";
+
+    /*
+     * The Thumbprint relative URI string (without #)
+     * Combine it with SOAPMESSAGE_NS11, #, to get the full URL
+     */
+    public static final String THUMBPRINT ="ThumbprintSHA1";
+    
+    /*
+     * The SAMLAssertionID relative URI string (without #)
+     */
+    public static final String SAML_ASSERTION_ID = "SAMLAssertionID";
+    /*
+     * The namespace prefixes used. We uses the same prefix convention
+     * as shown in the specifications
+     */
+    public static final String WSSE_PREFIX = "wsse";
+    public static final String WSSE11_PREFIX = "wsse11";
+    public static final String WSU_PREFIX = "wsu";
+    
+    /*
+     * Now the namespaces, local names, and prefixes of XML-SIG and XML-ENC
+     */
+    public static final String SIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+    public static final String SIG_PREFIX = "ds";
+    public static final String SIG_LN = "Signature";
+    public static final String ENC_NS = "http://www.w3.org/2001/04/xmlenc#";
+    public static final String ENC_PREFIX = "xenc";
+    public static final String ENC_KEY_LN = "EncryptedKey";
+    public static final String REF_LIST_LN = "ReferenceList";
+
+    /*
+     * The standard namesace definitions
+     */
+    public static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
+    public static final String XML_NS = "http://www.w3.org/XML/1998/namespace";
+    
+    /*
+     * The local names and attribute names used by WSS
+     */
+    public static final String USERNAME_TOKEN_LN = "UsernameToken";
+    public static final String BINARY_TOKEN_LN = "BinarySecurityToken";
+    public static final String TIMESTAMP_TOKEN_LN = "Timestamp";
+    public static final String USERNAME_LN = "Username";
+    public static final String PASSWORD_LN = "Password";
+    public static final String PASSWORD_TYPE_ATTR = "Type";
+    public static final String NONCE_LN = "Nonce";
+    public static final String CREATED_LN = "Created";
+    public static final String EXPIRES_LN = "Expires";
+    public static final String SIGNATURE_CONFIRMATION_LN = "SignatureConfirmation"; 
+    public static final String SALT_LN = "Salt";
+    public static final String ITERATION_LN = "Iteration";
+    
+    /*
+     * The definitions for SAML
+     */
+    public static final String SAML_NS = "urn:oasis:names:tc:SAML:1.0:assertion";
+    public static final String SAMLP_NS = "urn:oasis:names:tc:SAML:1.0:protocol";
+    public static final String ASSERTION_LN = "Assertion";
+    public static final String WSS_SAML_NS = "http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#";
+    public static final String WSS_SAML_ASSERTION = "SAMLAssertion-1.1";
+
+    //
+    // SOAP-ENV Namespaces
+    //
+    public static final String URI_SOAP11_ENV =
+            "http://schemas.xmlsoap.org/soap/envelope/";
+    public static final String URI_SOAP12_ENV =
+            "http://www.w3.org/2003/05/soap-envelope";
+
+    public static final String[] URIS_SOAP_ENV = {
+        URI_SOAP11_ENV,
+        URI_SOAP12_ENV,
+    };
+
+    // Misc SOAP Namespaces / URIs
+    public static final String URI_SOAP11_NEXT_ACTOR =
+            "http://schemas.xmlsoap.org/soap/actor/next";
+    public static final String URI_SOAP12_NEXT_ROLE =
+            "http://www.w3.org/2003/05/soap-envelope/role/next";
+    public static final String URI_SOAP12_NONE_ROLE =
+            "http://www.w3.org/2003/05/soap-envelope/role/none";
+    public static final String URI_SOAP12_ULTIMATE_ROLE =
+            "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver";
+
+    public static final String ELEM_ENVELOPE = "Envelope";
+    public static final String ELEM_HEADER = "Header";
+    public static final String ELEM_BODY = "Body";
+
+    public static final String ATTR_MUST_UNDERSTAND = "mustUnderstand";
+    public static final String ATTR_ACTOR = "actor";
+    public static final String ATTR_ROLE = "role";
+
+    public static final String NULL_NS = "Null";
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSAddUsernameToken#build(Document, String, String) UserNameToken}
+     * method to use a password digest to send the password information
+     * <p/>
+     * This is a required method as defined by WS Specification, Username token profile.
+     */
+    public static final String PW_DIGEST = "PasswordDigest";
+    /*
+     * The password type URI used in the username token 
+     */
+    public static final String PASSWORD_DIGEST = USERNAMETOKEN_NS + "#PasswordDigest";
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSAddUsernameToken#build(Document, String, String) UserNameToken}
+     * method to send the password in clear
+     * <p/>
+     * This is a required method as defined by WS Specification, Username token profile.
+     */
+    public static final String PW_TEXT = "PasswordText";
+    /*
+     * The password type URI used in the username token 
+     */
+    public static final String PASSWORD_TEXT = USERNAMETOKEN_NS + "#PasswordText";
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to encrypt the symmetric data encryption key with the RSA algoritm.
+     * <p/>
+     * This is a required method as defined by XML encryption.
+     */
+    public static final String KEYTRANSPORT_RSA15 = EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to encrypt the symmetric data encryption key with the RSA algoritm.
+     * <p/>
+     * This is a required method as defined by XML encryption.
+     * <p/>
+     * NOTE: This algorithm is not yet supported by WSS4J
+     */
+    public static final String KEYTRANSPORT_RSAOEP = EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to use triple DES as the symmetric algorithm to encrypt data.
+     * <p/>
+     * This is a required method as defined by XML encryption.
+     * The String to use in WSDD file (in accordance to w3c specifications:
+     * <br/>
+     * http://www.w3.org/2001/04/xmlenc#tripledes-cbc
+     */
+    public static final String TRIPLE_DES = EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to use AES with 128 bit key as the symmetric algorithm to encrypt data.
+     * <p/>
+     * This is a required method as defined by XML encryption.
+     * The String to use in WSDD file (in accordance to w3c specifications:
+     * <br/>
+     * http://www.w3.org/2001/04/xmlenc#aes128-cbc
+     */
+    public static final String AES_128 = EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to use AES with 256 bit key as the symmetric algorithm to encrypt data.
+     * <p/>
+     * This is a required method as defined by XML encryption.
+     * The String to use in WSDD file (in accordance to w3c specifications:
+     * <br/>
+     * http://www.w3.org/2001/04/xmlenc#aes256-cbc
+     */
+    public static final String AES_256 = EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to use AES with 192 bit key as the symmetric algorithm to encrypt data.
+     * <p/>
+     * This is a optional method as defined by XML encryption.
+     * The String to use in WSDD file (in accordance to w3c specifications:
+     * <br/>
+     * http://www.w3.org/2001/04/xmlenc#aes192-cbc
+     */
+    public static final String AES_192 = EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSignEnvelope#build(Document, Crypto) signature}
+     * method to use DSA with SHA1 (DSS) to sign data.
+     * <p/>
+     * This is a required method as defined by XML signature.
+     */
+    public static final String DSA = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSignEnvelope#build(Document, Crypto) signature}
+     * method to use RSA with SHA to sign data.
+     * <p/>
+     * This is a recommended method as defined by XML signature.
+     */
+    public static final String RSA = XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;
+
+    public static final String C14N_OMIT_COMMENTS = Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
+    public static final String C14N_WITH_COMMENTS = Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
+    public static final String C14N_EXCL_OMIT_COMMENTS = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+    public static final String C14N_EXCL_WITH_COMMENTS = Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSignEnvelope#build(Document, Crypto) signing}
+     * method to send the signing certificate as a
+     * <code>BinarySecurityToken</code>.
+     * <p/>
+     * The signing method takes the signing certificate, converts it to a
+     * <code>BinarySecurityToken</code>, puts it in the security header,
+     * and inserts a <code>Reference</code> to the binary security token
+     * into the <code>wsse:SecurityReferenceToken</code>. Thus the whole
+     * signing certificate is transfered to the receiver.
+     * The X509 profile recommends to use {@link #ISSUER_SERIAL} instead
+     * of sending the whole certificate.
+     * <p/>
+     * Please refer to WS Security specification X509 profile, chapter 3.3.2
+     * and to WS Security specification, chapter 7.2
+     * <p/>
+     * Note: only local refernces to BinarySecurityToken are supported
+     */
+    public static final int BST_DIRECT_REFERENCE = 1;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSSignEnvelope#build(Document, Crypto) signing}
+     * or the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to send the issuer name and the serial number of a
+     * certificate to the receiver.
+     * <p/>
+     * In contrast to {@link #BST_DIRECT_REFERENCE} only the issuer name
+     * and the serial number of the signiung certificate are sent to the
+     * receiver. This reduces the amount of data being sent. The ecnryption
+     * method uses the private key associated with this certificate to encrypt
+     * the symmetric key used to encrypt data.
+     * <p/>
+     * Please refer to WS Security specification X509 profile, chapter 3.3.3
+     */
+    public static final int ISSUER_SERIAL = 2;
+
+    /**
+     * Sets the {@link org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption}
+     * method to send the certificate used to encrypt the symmetric key.
+     * <p/>
+     * The encryption method uses the private key associated with this certificate
+     * to encrypr the symmetric key used to encrypt data. The certificate is
+     * converted into a <code>KeyIdentfier</code> token and sent to the receiver.
+     * Thus the complete certificate data is transfered to receiver.
+     * The X509 profile recommends to use {@link #ISSUER_SERIAL} instead
+     * of sending the whole certificate.
+     * <p/>
+     * <p/>
+     * Please refer to WS Security specification X509 profile, chapter 7.3
+     */
+    public static final int X509_KEY_IDENTIFIER = 3;
+    /**
+     * Sets the
+     * {@link org.apache.ws.security.message.WSSignEnvelope#build(Document, Crypto)
+     * signing}
+     * method to send a <code>SubjectKeyIdentifier</code> to identify
+     * the signing certificate.
+     * <p/>
+     * Refer to WS Security specification X509 profile, chapter 3.3.1
+     * This identification token is not yet fully tested by WSS4J. The
+     * WsDoAllSender does not include the X.509 certificate as
+     * <code>BinarySecurityToken</code> in the request message.
+     */
+    public static final int SKI_KEY_IDENTIFIER = 4;
+
+    /**
+     * Embeds a keyinfo/key name into the EncryptedData element.
+     * <p/>
+     * Refer to WS Security specification X509 profile
+     */
+    public static final int EMBEDDED_KEYNAME = 5;
+    /**
+     * Embeds a keyinfo/wsse:SecurityTokenReference into EncryptedData element.
+     */
+    public static final int EMBED_SECURITY_TOKEN_REF = 6;
+    
+    /**
+     * <code>UT_SIGNING</code> is used interally only to set a specific Signature
+     * behaviour.
+     * 
+     * The signing token is constructed from values in the UsernameToken according
+     * to WS-Trust specification.
+     */
+    public static final int UT_SIGNING = 7;
+    
+    /**
+     * <code>THUMPRINT_IDENTIFIER</code> is used to set the specific key identifier
+     * ThumbprintSHA1.
+     * 
+     * This identifier uses the SHA-1 digest of a security token to
+     * identify the security token. Please refer to chapter 7.2 of the OASIS WSS 1.1
+     * specification.
+     * 
+     */
+    public static final int THUMBPRINT_IDENTIFIER = 8;
+
+    /*
+     * The following values are bits that can be combined to for a set.
+     * Be carefull when selecting new values.
+     */
+    public static final int NO_SECURITY = 0;
+    public static final int UT = 0x1; // perform UsernameToken
+    public static final int SIGN = 0x2; // Perform Signature
+    public static final int ENCR = 0x4; // Perform Encryption
+
+    /*
+     * Attention: the signed/Unsigned types identify if WSS4J uses
+     * the SAML token for signature, signature key or not. It does
+     * not mean if the token contains an enveloped signature.
+     */
+    public static final int ST_UNSIGNED = 0x8; // perform SAMLToken unsigned
+    public static final int ST_SIGNED = 0x10; // perform SAMLToken signed
+
+    public static final int TS = 0x20; // insert Timestamp
+    public static final int UT_SIGN = 0x40; // perform sinagture with UT secrect key
+    public static final int SC = 0x80;      // this is a SignatureConfirmation
+
+    public static final int NO_SERIALIZE = 0x100;
+    public static final int SERIALIZE = 0x200;
+
+    /**
+     * Length of UsernameToken derived key used by .NET WSE to sign a message.
+     */
+    public static final int WSE_DERIVED_KEY_LEN = 16;
+    public static final String LABEL_FOR_DERIVED_KEY = "WS-Security";
+
+}
+
diff --git a/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java b/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
new file mode 100644
index 0000000..024240c
--- /dev/null
+++ b/src/org/apache/ws/security/WSDerivedKeyTokenPrincipal.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import java.security.Principal;
+
+/**
+ * This class implements the <code>Principal</code> interface and
+ * represents a <code>DerivedKeyToken</code>.
+ * The principal's name will be the <code>wsu:Id</code> valud of the 
+ * <code>DerivedKeyToken</code>
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class WSDerivedKeyTokenPrincipal implements Principal {
+
+    private String id;
+    private String nonce;
+    private String label;
+    private int length;
+    private int offset;
+    
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public int getLength() {
+        return length;
+    }
+
+    public void setLength(int length) {
+        this.length = length;
+    }
+
+    public int getOffset() {
+        return offset;
+    }
+
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+
+    public String getNonce() {
+        return nonce;
+    }
+
+    public WSDerivedKeyTokenPrincipal(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return id;
+    }
+    
+    public void setNonce(String nonce) {
+        this.nonce = nonce;
+    }
+
+}
diff --git a/src/org/apache/ws/security/WSDocInfo.java b/src/org/apache/ws/security/WSDocInfo.java
new file mode 100644
index 0000000..eccebe7
--- /dev/null
+++ b/src/org/apache/ws/security/WSDocInfo.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+/**
+ * WSDocInfo holds information about the document to process. Together
+ * with the WSDocInfoStore it provides a method to store and access document
+ * information about BinarySecurityToken, used Crypto, and others.
+ * </p>
+ * Using the Document's hash a caller can identify a document and get
+ * the stored information that me be necessary to process the document.
+ * The main usage for this is (are) the transformation functions that
+ * are called during Signature/Verfication process. 
+ * 
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ *
+ */
+
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.processor.Processor;
+import org.w3c.dom.Element;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+public class WSDocInfo {
+    int hash;
+    Crypto crypto = null;
+    Vector bst = null;
+    Element assertion = null;
+    Vector processors = null;
+
+    public WSDocInfo(int hash) {
+        this.hash = hash;
+    }
+
+    /**
+     * Clears the info data except the hash code
+     */
+    public void clear() {
+        crypto = null;
+        assertion = null;
+        if (bst != null && bst.size() > 0) {
+            bst.removeAllElements();
+        }
+        if (processors != null && processors.size() > 0) {
+        	processors.removeAllElements();
+        }
+        
+        bst = null;
+        processors = null;
+    }
+
+    /**
+     * Get a BinarySecurityToken for the given Id
+     *
+     * @param uri is the relative uri (starts with #) of the id
+     * @return the BST element or null if nothing found
+     */
+    public Element getBst(String uri) {
+        String id = uri.substring(1);
+        Element elem = null;
+
+        if (bst != null) {
+            for (Enumeration e = bst.elements(); e.hasMoreElements();) {
+                elem = (Element) e.nextElement();
+                String cId = elem.getAttribute("Id");
+                if (id.equals(cId)) {
+                    break;
+                }
+            }
+        }
+        return elem;
+    }
+
+    /**
+     * Get a Processor for the given Id
+     *
+     * @param id is the Id to look for
+     * @return the Security processor identified with this Id or null if nothing found
+     */
+    public Processor getProcessor(String id) {
+    	
+    	if (id == null) {
+    		return null;
+    	}
+
+    	Processor p = null;
+        if (processors != null) {
+            for (Enumeration e = processors.elements(); e.hasMoreElements();) {
+                p = (Processor) e.nextElement();
+                String cId = p.getId();
+                if (id.equals(cId)) {
+                    break;
+                }
+            }
+        }
+        return p;
+    }
+    
+    /**
+     * Store a Processor for later access.
+     * 
+     * @param p is the Processor to store
+     */
+    public void setProcessor(Processor p) {
+        if (processors == null) {
+        	processors = new Vector();
+        }
+        processors.add(p);
+    }
+    
+    /**
+     * @return the signature crypto class used to process
+     *         the signature/verfiy
+     */
+    public Crypto getCrypto() {
+        return crypto;
+    }
+
+    /**
+     * @return the hash value of the document
+     */
+    public int getHash() {
+        return hash;
+    }
+
+    /**
+     * @param elem is the BinarySecurityToken to store
+     */
+    public void setBst(Element elem) {
+        if (bst == null) {
+            bst = new Vector();
+        }
+        bst.add(elem);
+    }
+
+    /**
+     * @param crypto is the signature crypto class used to
+     *               process signature/verify
+     */
+    public void setCrypto(Crypto crypto) {
+        this.crypto = crypto;
+    }
+
+    /**
+     * @return Returns the assertion.
+     */
+    public Element getAssertion() {
+        return assertion;
+    }
+
+    /**
+     * @param assertion The assertion to set.
+     */
+    public void setAssertion(Element assertion) {
+        this.assertion = assertion;
+    }
+}
diff --git a/src/org/apache/ws/security/WSDocInfoStore.java b/src/org/apache/ws/security/WSDocInfoStore.java
new file mode 100644
index 0000000..0a7464b
--- /dev/null
+++ b/src/org/apache/ws/security/WSDocInfoStore.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+/**
+ * WSDocInfoStore store WSDocInfo structure in a static Hash. 
+ * 
+ * Also the access methods are static. Thus it is possible to exchange
+ * WSDocInfo between otherwise unrelated functions/methods.
+ * The main usage for this is (are) the transformation functions that
+ * are called during Signature/Verfication process. 
+ * 
+ * @author Werner Dittmann (Werner.Dittmann@apache.org)
+ */
+
+import java.util.Hashtable;
+
+public class WSDocInfoStore {
+
+    static Hashtable storage = new Hashtable(10);
+
+    public static WSDocInfo lookup(int hash) {
+        Integer intObj = new Integer(hash);
+        return (WSDocInfo) storage.get(intObj);
+    }
+
+    public static void store(WSDocInfo info) {
+        Integer intObj = new Integer(info.getHash());
+        if (storage.containsKey(intObj)) {
+            return;
+        }
+        storage.put(intObj, info);
+    }
+
+    public static void delete(int hash) {
+        Integer intObj = new Integer(hash);
+        WSDocInfo wsInfo = (WSDocInfo) storage.get(intObj);
+        if (wsInfo != null) {
+            storage.remove(intObj);
+        }
+    }
+
+    public static void delete(WSDocInfo info) {
+        delete(info.getHash());
+    }
+}
diff --git a/src/org/apache/ws/security/WSEncryptionPart.java b/src/org/apache/ws/security/WSEncryptionPart.java
new file mode 100644
index 0000000..4704c5b
--- /dev/null
+++ b/src/org/apache/ws/security/WSEncryptionPart.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+/**
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ */
+public class WSEncryptionPart {
+
+    private String name;
+    private String namespace;
+    private String encModifier;
+    private String id;
+
+
+    /**
+     * Constructor to initialize part structure with element, namespace, and modifier.
+     * 
+     * This constructor initializes the parts structure to lookup for a
+     * fully qualified name of an element to encrypt or sign. The modifier
+     * controls how encryption encrypts the element, signature processing does
+     * not use the modifier information.
+     * 
+     * <p/>
+     * 
+     * Regarding the modifier ("Content" or "Element") refer to the W3C
+     * XML Encryption specification. 
+     * 
+     * @param nm Element's name
+     * @param nmspace Element's namespace
+     * @param encMod The encryption modifier
+     */
+    public WSEncryptionPart(String nm, String nmspace, String encMod) {
+        name = nm;
+        namespace = nmspace;
+        encModifier = encMod;
+        id = null;
+    }
+
+    /**
+     * Constructor to initialize part structure with element id.
+     * 
+     * This constructor initializes the parts structure to lookup for a
+     * an element with the given Id to encrypt or sign. 
+     * 
+     * @param id The Id to of the element to process
+     */
+    public WSEncryptionPart(String id) {
+        this.id = id;
+        name = namespace = encModifier = null;
+    }
+    
+    /**
+     * Constructor to initialize part structure with element id and modifier.
+     * 
+     * This constructor initializes the parts structure to lookup for a
+     * an element with the given Id to encrypt or sign. The modifier
+     * controls how encryption encrypts the element, signature processing does
+     * not use the modifier information.
+     * 
+     * <p/>
+     * 
+     * Regarding the modifier ("Content" or "Element") refer to the W3C
+     * XML Encryption specification. 
+     * 
+     * @param id The Id to of the element to process
+     * @param encMod The encryption modifier
+     */
+    public WSEncryptionPart(String id, String encMod) {
+        this.id = id;
+        encModifier = encMod;
+        name = namespace = null;
+    }
+
+    /**
+     * @return the local name of the element to encrypt.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return the namespace of the element to encrypt
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * @return the encryption modifier
+     */
+    public String getEncModifier() {
+        return encModifier;
+    }
+
+    /**
+     * @return Returns the id.
+     */
+    public String getId() {
+        return id;
+    }
+}
diff --git a/src/org/apache/ws/security/WSPasswordCallback.java b/src/org/apache/ws/security/WSPasswordCallback.java
new file mode 100644
index 0000000..e3d71a6
--- /dev/null
+++ b/src/org/apache/ws/security/WSPasswordCallback.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import javax.security.auth.callback.Callback;
+
+/**
+ * Simple class to provide a password callback mechanism.
+ * <p/>
+ * It uses the JAAS authentication mechanisms and callback methods.
+ * In addition to the identifier (user name) this class also provides
+ * information what type of information the callback <code>handle</code>
+ * method shall provide.
+ * <p/>
+ * The <code> WSPasswordCallback</code> class defines the following usage
+ * codes:
+ * <ul>
+ * <li><code>UNKNOWN</code> - an unknown usage. Never used by the WSS4J
+ * implementation and shall be treated as an error by the <code>handle
+ * </code> method.</li>
+ * <li><code>DECRYPT</code> - need a password to get the private key of
+ * this identifier (username) from    the keystore. WSS4J uses this private
+ * key to decrypt the session (symmetric) key. Because the encryption
+ * method uses the public key to encrypt the session key it needs no
+ * password (a public key is usually not protected by a password).</li>
+ * <li><code>USERNAME_TOKEN</code> - need the password to fill in or to
+ * verify a <code>UsernameToken</code>.</li>
+ * <li><code>SIGNATURE</code> - need the password to get the private key of
+ * this identifier (username) from    the keystore. WSS4J uses this private
+ * key to produce a signature. The signature verfication uses the public
+ * key to verfiy the signature.</li>
+ * <li><code>KEY_NAME</code> - need the <i>key</i>, not the password,
+ * associated with the identifier. WSS4J uses this key to encrypt or
+ * decrypt parts of the SOAP request. Note, the key must match the
+ * symmetric encryption/decryption algorithm specified (refer to
+ * {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_SYM_ALGO}).</li>
+ * <li><code>USERNAME_TOKEN_UNKNOWN</code> - either an not specified 
+ * password type or a password type passwordText. In these both cases <b>only</b>
+ * the password variable is <b>set</b>. The callback class now may check if
+ * the username and password match. If they don't match the callback class must
+ * throw an exception. The exception can be a UnsupportedCallbackException or
+ * an IOException.</li>
+ * <li><code>SECURITY_CONTEXT_TOKEN</code> - need the key to to be associated 
+ * with a <code>wsc:SecurityContextToken</code>.</li>
+ * </ul>
+ *
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com).
+ */
+
+public class WSPasswordCallback implements Callback {
+
+    public static final int UNKNOWN = 0;
+    public static final int DECRYPT = 1;
+    public static final int USERNAME_TOKEN = 2;
+    public static final int SIGNATURE = 3;
+    public static final int KEY_NAME = 4;
+    public static final int USERNAME_TOKEN_UNKNOWN = 5;
+    public final static int SECURITY_CONTEXT_TOKEN = 6; 
+
+    private String identifier;
+    private String password;
+    private byte[] key;
+    private int usage;
+    private String passwordType;
+
+    /**
+     * Constructor.
+     *
+     * @param id The application called back must supply the password for
+     *           this identifier.
+     */
+    public WSPasswordCallback(String id, int usage) {
+    	this(id, null, null, usage);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param id The application called back must supply the password for
+     *           this identifier.
+     */
+    public WSPasswordCallback(String id, String pw, String type, int usage) {
+        identifier = id;
+        password = pw;
+        passwordType = type;
+        this.usage = usage;
+    }
+    /**
+     * Get the identifier.
+     * <p/>
+     *
+     * @return The identifier
+     */
+    public String getIdentifer() {
+        return identifier;
+    }
+
+    /**
+     * Set the password.
+     * <p/>
+     *
+     * @param passwd is the password associated to the identifier
+     */
+    public void setPassword(String passwd) {
+        password = passwd;
+    }
+
+    /**
+     * Get the password.
+     * <p/>
+     *
+     * @return The password
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * Set the Key.
+     * <p/>
+     *
+     * @param key is the key associated to the identifier
+     */
+    public void setKey(byte[] key) {
+        this.key = key;
+    }
+
+    /**
+     * Get the key.
+     * <p/>
+     *
+     * @return The key
+     */
+    public byte[] getKey() {
+        return this.key;
+    }
+
+    /**
+     * Get the usage.
+     * <p/>
+     *
+     * @return The usage for this callback
+     */
+    public int getUsage() {
+        return usage;
+    }
+	/**
+	 * The password type is only relevant for usage <code>USERNAME_TOKEN</code>
+	 * and <code>USERNAME_TOKEN_UNKNOWN</code>.
+	 * 
+	 * @return Returns the passwordType.
+	 */
+	public String getPasswordType() {
+		return passwordType;
+	}
+}
+
diff --git a/src/org/apache/ws/security/WSSConfig.java b/src/org/apache/ws/security/WSSConfig.java
new file mode 100644
index 0000000..c9fa282
--- /dev/null
+++ b/src/org/apache/ws/security/WSSConfig.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import java.util.HashMap;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.action.Action;
+import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.Loader;
+import org.apache.xml.security.transforms.Transform;
+
+/**
+ * WSSConfig <p/> Carries configuration data so the WSS4J spec compliance can be
+ * modified in runtime. Configure an instance of this object only if you need
+ * WSS4J to emulate certain industry clients or previous OASIS specifications
+ * for WS-Security interoperability testing purposes. <p/> The default settings
+ * follow the latest OASIS and changing anything might violate the OASIS specs.
+ * <p/> <b>WARNING: changing the default settings will break the compliance with
+ * the latest specs. Do this only if you know what you are doing.</b> <p/>
+ * 
+ * @author Rami Jaamour (rjaamour@parasoft.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public class WSSConfig {
+    private static Log log = LogFactory.getLog(WSSConfig.class.getName());
+
+    protected static WSSConfig defaultConfig = getNewInstance();
+
+    protected boolean wsiBSPCompliant = false;
+
+    /**
+     * Set the timestamp precision mode. If set to <code>true</code> then use
+     * timestamps with milliseconds, otherwise omit the millisconds. As per XML
+     * Date/Time specification the default is to include the milliseconds.
+     */
+    protected boolean precisionInMilliSeconds = true;
+
+    protected boolean enableSignatureConfirmation = true;
+
+    /**
+     * If set to true then the timestamp handling will throw an expcetion if the
+     * timestamp contains an expires element and the semantics are expired.
+     * 
+     * If set to false, not expetion will be thrown, even if the semantics are
+     * expired.
+     */
+    protected boolean timeStampStrict = true;
+
+    protected HashMap jceProvider = new HashMap(10);
+
+    protected WSSConfig() {
+        org.apache.xml.security.Init.init();
+        /*
+         * The last provider added has precedence, that is if JuiCE can be add
+         * then WSS4J uses this provider.
+         */
+        addJceProvider("BC",
+                "org.bouncycastle.jce.provider.BouncyCastleProvider");
+        addJceProvider("JuiCE",
+                "org.apache.security.juice.provider.JuiCEProviderOpenSSL");
+        Transform.init();
+        try {
+            Transform.register(STRTransform.implementedTransformURI,
+                    "org.apache.ws.security.transform.STRTransform");
+        } catch (Exception ex) {
+        }
+    }
+
+    /**
+     * @return a new WSSConfig instance configured with the default values
+     *         (values identical to
+     *         {@link #getDefaultWSConfig getDefaultWSConfig()})
+     */
+    public static WSSConfig getNewInstance() {
+        WSSConfig config = new WSSConfig();
+        return config;
+    }
+
+    /**
+     * returns a static WSConfig instance that is configured with the latest
+     * OASIS WS-Seurity settings.
+     */
+    public static WSSConfig getDefaultWSConfig() {
+        return defaultConfig;
+    }
+
+    /**
+     * Checks if we are in WS-I Basic Security Profile compliance mode
+     * 
+     * @return TODO
+     */
+    public boolean isWsiBSPCompliant() {
+        return wsiBSPCompliant;
+    }
+
+    /**
+     * Set the WS-I Basic Security Profile compliance mode. The default is false
+     * (dues to .Net interop problems).
+     * 
+     * @param wsiBSPCompliant
+     */
+    public void setWsiBSPCompliant(boolean wsiBSPCompliant) {
+        this.wsiBSPCompliant = wsiBSPCompliant;
+    }
+
+    /**
+     * Checks if we need to use milliseconds in timestamps
+     * 
+     * @return TODO
+     */
+    public boolean isPrecisionInMilliSeconds() {
+        return precisionInMilliSeconds;
+    }
+
+    /**
+     * Set the precision in milliseconds
+     * 
+     * @param precisionInMilliSeconds
+     *            TODO
+     */
+    public void setPrecisionInMilliSeconds(boolean precisionInMilliSeconds) {
+        this.precisionInMilliSeconds = precisionInMilliSeconds;
+    }
+
+    /**
+     * @return Returns the enableSignatureConfirmation.
+     */
+    public boolean isEnableSignatureConfirmation() {
+        return enableSignatureConfirmation;
+    }
+
+    /**
+     * @param enableSignatureConfirmation
+     *            The enableSignatureConfirmation to set.
+     */
+    public void setEnableSignatureConfirmation(
+            boolean enableSignatureConfirmation) {
+        this.enableSignatureConfirmation = enableSignatureConfirmation;
+    }
+
+    /**
+     * @return Returns if we shall throw an exception on expired request
+     *         semantic
+     */
+    public boolean isTimeStampStrict() {
+        return timeStampStrict;
+    }
+
+    /**
+     * @param timeStampStrict
+     *            If true throw an exception on expired request semantic
+     */
+    public void setTimeStampStrict(boolean timeStampStrict) {
+        this.timeStampStrict = timeStampStrict;
+    }
+
+    /**
+     * Lookup action
+     * 
+     * @param action
+     * @return An action class to create a security token
+     * @throws WSSecurityException
+     */
+    public Action getAction(int action) throws WSSecurityException {
+        String name = null;
+        switch (action) {
+        case WSConstants.UT:
+            name = "org.apache.ws.security.action.UsernameTokenAction";
+            break;
+
+        case WSConstants.ENCR:
+            name = "org.apache.ws.security.action.EncryptionAction";
+            break;
+
+        case WSConstants.SIGN:
+            name = "org.apache.ws.security.action.SignatureAction";
+            break;
+
+        case WSConstants.ST_SIGNED:
+            name = "org.apache.ws.security.action.SAMLTokenSignedAction";
+            break;
+
+        case WSConstants.ST_UNSIGNED:
+            name = "org.apache.ws.security.action.SAMLTokenUnsignedAction";
+            break;
+
+        case WSConstants.TS:
+            name = "org.apache.ws.security.action.TimestampAction";
+            break;
+
+        case WSConstants.UT_SIGN:
+            name = "org.apache.ws.security.action.UsernameTokenSignedAction";
+            break;
+        case WSConstants.SC:
+            name = "org.apache.ws.security.action.SignatureConfirmationAction";
+            break;
+        }
+        if (name == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unknownAction", new Object[] { new Integer(action) });
+        }
+        try {
+            return (Action) Loader.loadClass(name).newInstance();
+        } catch (Throwable t) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unableToLoadClass", new Object[] { name });
+        }
+    }
+
+    public Processor getProcessor(QName el) throws WSSecurityException {
+        String name = null;
+        if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
+            name = "org.apache.ws.security.processor.SAMLTokenProcessor";
+        } else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {
+            name = "org.apache.ws.security.processor.EncryptedKeyProcessor";
+        } else if (el.equals(WSSecurityEngine.SIGNATURE)) {
+            name = "org.apache.ws.security.processor.SignatureProcessor";
+        } else if (el.equals(WSSecurityEngine.timeStamp)) {
+            name = "org.apache.ws.security.processor.TimestampProcessor";
+        } else if (el.equals(WSSecurityEngine.usernameToken)) {
+            name = "org.apache.ws.security.processor.UsernameTokenProcessor";
+        } else if (el.equals(WSSecurityEngine.REFERENCE_LIST)) {
+            name = "org.apache.ws.security.processor.ReferenceListProcessor";
+        } else if (el.equals(WSSecurityEngine.signatureConfirmation)) {
+            name = "org.apache.ws.security.processor.SignatureConfirmationProcessor";
+        } else if (el.equals(WSSecurityEngine.DERIVED_KEY_TOKEN)) {
+            name = "org.apache.ws.security.processor.DerivedKeyTokenProcessor";
+        } else if(el.equals(WSSecurityEngine.SECURITY_CONTEXT_TOKEN)) {
+            name = "org.apache.ws.security.processor.SecurityContextTokenProcessor";
+        }
+
+        if (name != null) {
+            try {
+                return (Processor) Loader.loadClass(name).newInstance();
+            } catch (Throwable t) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "unableToLoadClass", new Object[] { name });
+            }
+        }
+        return null;
+    }
+
+    private boolean loadProvider(String id, String className) {
+        try {
+            Class c = Loader.loadClass(className);
+            if (java.security.Security.getProvider(id) == null) {
+                if (log.isDebugEnabled()) {
+                    log.debug("The provider " + id
+                            + " had to be added to the java.security.Security");
+                }
+                int ret =java.security.Security.insertProviderAt(
+                        (java.security.Provider) c.newInstance(), 2);
+                if (log.isDebugEnabled()) {
+                    log.debug("The provider " + id + " was added at: "
+                            + ret);
+                }                
+            }
+            return true;
+        } catch (Throwable t) {
+            if (log.isDebugEnabled()) {
+                log.debug("The provider " + id + " could not be added: "
+                        + t.getMessage());
+            }
+            return false;
+        }
+
+    }
+
+    /**
+     * Add a new JCE security provider to use for WSS4J.
+     * 
+     * If the provider is not already known the method loads a security provider
+     * class and adds the provider to the java security service.
+     * 
+     * 
+     * @param id
+     *            The id string of the provider
+     * @param className
+     *            Name of the class the implements the provider. This class must
+     *            be a subclass of <code>java.security.Provider</code>
+     * 
+     * @return Returns <code>true</code> if the provider was successfully
+     *         added, <code>false</code> otherwise.
+     */
+    public boolean addJceProvider(String id, String className) {
+        if (jceProvider.get(id) == null && loadProvider(id, className)) {
+            jceProvider.put(id, className);
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/src/org/apache/ws/security/WSSecurityEngine.java b/src/org/apache/ws/security/WSSecurityEngine.java
new file mode 100644
index 0000000..f3b0bba
--- /dev/null
+++ b/src/org/apache/ws/security/WSSecurityEngine.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.processor.Processor;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+
+import java.util.Vector;
+
+/**
+ * WS-Security Engine.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de).
+ */
+public class WSSecurityEngine {
+    public static final String VALUE_TYPE = "ValueType";
+    private static Log log = LogFactory.getLog(WSSecurityEngine.class.getName());
+    private static Log tlog =
+            LogFactory.getLog("org.apache.ws.security.TIME");
+
+    private static WSSecurityEngine engine = null;
+    private static WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+    private boolean doDebug = false;
+    /**
+     * <code>wsse:BinarySecurityToken</code> as defined by WS Security specification
+     */
+    public static final QName binaryToken = new QName(WSConstants.WSSE_NS, WSConstants.BINARY_TOKEN_LN);
+    /**
+     * <code>wsse:UsernameToken</code> as defined by WS Security specification
+     */
+    public static final QName usernameToken = new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN);
+    /**
+     * <code>wsu:Timestamp</code> as defined by OASIS WS Security specification,
+     */
+    public static final QName timeStamp = new QName(WSConstants.WSU_NS, WSConstants.TIMESTAMP_TOKEN_LN);
+    /**
+     * <code>wsse11:signatureConfirmation</code> as defined by OASIS WS Security specification,
+     */
+   public static final QName signatureConfirmation = new QName(WSConstants.WSSE11_NS, WSConstants.SIGNATURE_CONFIRMATION_LN);
+    /**
+     * <code>ds:Signature</code> as defined by XML Signature specification,
+     * enhanced by WS Security specification
+     */
+    public static final QName SIGNATURE = new QName(WSConstants.SIG_NS, WSConstants.SIG_LN);
+    /**
+     * <code>xenc:EncryptedKey</code> as defined by XML Encryption specification,
+     * enhanced by WS Security specification
+     */
+    public static final QName ENCRYPTED_KEY = new QName(WSConstants.ENC_NS, WSConstants.ENC_KEY_LN);
+    /**
+     * <code>xenc:ReferenceList</code> as defined by XML Encryption specification,
+     */
+    public static final QName REFERENCE_LIST = new QName(WSConstants.ENC_NS, WSConstants.REF_LIST_LN);
+    /**
+     * <code>saml:Assertion</code> as defined by SAML specification
+     */
+    public static final QName SAML_TOKEN = new QName(WSConstants.SAML_NS, WSConstants.ASSERTION_LN);
+
+    /**
+     * <code>wsc:DerivedKeyToken</code> as defined by WS-SecureConversation specification
+     */
+    public static final QName DERIVED_KEY_TOKEN = new QName(ConversationConstants.WSC_NS, ConversationConstants.DERIVED_KEY_TOKEN_LN);
+
+    /**
+     * <code>wsc:SecurityContextToken</code> as defined by WS-SecureConversation specification
+     */
+    public static final QName SECURITY_CONTEXT_TOKEN = new QName(ConversationConstants.WSC_NS, ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+    
+    public WSSecurityEngine() {
+    }
+
+    /**
+     * Get a singleton instance of security engine.
+     * <p/>
+     *
+     * @return ws-security engine.
+     */
+    public synchronized static WSSecurityEngine getInstance() {
+        if (engine == null) {
+            engine = new WSSecurityEngine();
+        }
+        return engine;
+    }
+
+    /**
+     * @param wsc set the static WSSConfig to other than default
+     */
+    public static void setWssConfig(WSSConfig wsc) {
+        wssConfig = wsc;
+    }
+    /**
+     * Process the security header given the soap envelope as W3C document.
+     * <p/>
+     * This is the main entry point to verify or decrypt a SOAP enevelope.
+     * First check if a <code>wsse:Security</code> is availabe with the
+     * defined actor.
+     *
+     * @param doc    the SOAP envelope as {@link Document}
+     * @param actor  the engine works on behalf of this <code>actor</code>. Refer
+     *               to the SOAP specification about <code>actor</code> or <code>role
+     *               </code>
+     * @param cb     a callback hander to the caller to resolve passwords during
+     *               encryption and {@link UsernameToken} handling
+     * @param crypto the object that implements the access to the keystore and the
+     *               handling of certificates.
+     * @return a result vector
+     * @throws WSSecurityException
+     * @see WSSecurityEngine#processSecurityHeader(Element securityHeader, CallbackHandler cb,Crypto sigCrypto, Crypto decCrypto)
+     */
+    public Vector processSecurityHeader(Document doc,
+                                        String actor,
+                                        CallbackHandler cb,
+                                        Crypto crypto)
+            throws WSSecurityException {
+        return processSecurityHeader(doc, actor, cb, crypto, crypto);
+    }
+
+    /**
+     * Process the security header given the soap envelope as W3C document.
+     * <p/>
+     * This is the main entry point to verify or decrypt a SOAP enevelope.
+     * First check if a <code>wsse:Security</code> is availabe with the
+     * defined actor.
+     *
+     * @param doc       the SOAP envelope as {@link Document}
+     * @param actor     the engine works on behalf of this <code>actor</code>. Refer
+     *                  to the SOAP specification about <code>actor</code> or <code>role
+     *                  </code>
+     * @param cb        a callback hander to the caller to resolve passwords during
+     *                  encryption and {@link UsernameToken} handling
+     * @param sigCrypto the object that implements the access to the keystore and the
+     *                  handling of certificates for Signature
+     * @param decCrypto the object that implements the access to the keystore and the
+     *                  handling of certificates for Decryption
+     * @return a result vector
+     * @throws WSSecurityException
+     * @see WSSecurityEngine#processSecurityHeader(Element securityHeader, CallbackHandler cb,Crypto sigCrypto, Crypto decCrypto)
+     */
+    public Vector processSecurityHeader(Document doc,
+                                        String actor,
+                                        CallbackHandler cb,
+                                        Crypto sigCrypto,
+                                        Crypto decCrypto)
+            throws WSSecurityException {
+
+        doDebug = log.isDebugEnabled();
+        if (doDebug) {
+            log.debug("enter processSecurityHeader()");
+        }
+
+        if (actor == null) {
+            actor = "";
+        }
+        Vector wsResult = null;
+        SOAPConstants sc = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+        Element elem = WSSecurityUtil.getSecurityHeader(doc, actor, sc);
+        if (elem != null) {
+            if (doDebug) {
+                log.debug("Processing WS-Security header for '" + actor
+                        + "' actor.");
+            }
+            wsResult = processSecurityHeader(elem, cb, sigCrypto, decCrypto);
+        }
+        return wsResult;
+    }
+
+    /**
+     * Process the security header given the <code>wsse:Security</code> DOM
+     * Element. 
+     * 
+     * This function loops over all direct child elements of the
+     * <code>wsse:Security</code> header. If it finds a knwon element, it
+     * transfers control to the appropriate handling function. The method
+     * processes the known child elements in the same order as they appear in
+     * the <code>wsse:Security</code> element. This is in accordance to the WS
+     * Security specification. <p/>
+     * 
+     * Currently the functions can handle the following child elements:
+     * 
+     * <ul>
+     * <li>{@link #SIGNATURE <code>ds:Signature</code>}</li>
+     * <li>{@link #ENCRYPTED_KEY <code>xenc:EncryptedKey</code>}</li>
+     * <li>{@link #REFERENCE_LIST <code>xenc:ReferenceList</code>}</li>
+     * <li>{@link #usernameToken <code>wsse:UsernameToken</code>}</li>
+     * <li>{@link #timeStamp <code>wsu:Timestamp</code>}</li>
+     * </ul>
+     *
+     * @param securityHeader the <code>wsse:Security</code> header element
+     * @param cb             a callback hander to the caller to resolve passwords during
+     *                       encryption and {@link UsernameToken}handling
+     * @param sigCrypto      the object that implements the access to the keystore and the
+     *                       handling of certificates used for Signature
+     * @param decCrypto      the object that implements the access to the keystore and the
+     *                       handling of certificates used for Decryption
+     * @return a Vector of {@link WSSecurityEngineResult}. Each element in the
+     *         the Vector represents the result of a security action. The elements
+     *         are ordered according to the sequence of the security actions in the
+     *         wsse:Signature header. The Vector maybe empty if no security processing
+     *         was performed.
+     * @throws WSSecurityException
+     */
+    protected Vector processSecurityHeader(Element securityHeader,
+                                           CallbackHandler cb,
+                                           Crypto sigCrypto,
+                                           Crypto decCrypto) throws WSSecurityException {
+
+        long t0 = 0, t1 = 0, t2 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+        /*
+         * Gather some info about the document to process and store
+         * it for retrival. Store the implemenation of signature crypto
+         * (no need for encryption --- yet)
+         */
+        WSDocInfo wsDocInfo = new WSDocInfo(securityHeader.getOwnerDocument().hashCode());
+        wsDocInfo.setCrypto(sigCrypto);
+
+        NodeList list = securityHeader.getChildNodes();
+        int len = list.getLength();
+        Node elem;
+        if (tlog.isDebugEnabled()) {
+            t1 = System.currentTimeMillis();
+        }
+        Vector returnResults = new Vector();
+
+        for (int i = 0; i < len; i++) {
+            elem = list.item(i);
+            if (elem.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
+            Processor p = wssConfig.getProcessor(el);
+            /*
+             * Call the processor for this token. After the processor returns, 
+             * store it for later retrival. The token processor may store some
+             * information about the processed token
+             */
+            if (p != null) {
+                p.handleToken((Element) elem, sigCrypto, decCrypto, cb, wsDocInfo, returnResults, wssConfig);
+                wsDocInfo.setProcessor(p);
+            } else {
+                /*
+                * Add check for a BinarySecurityToken, add info to WSDocInfo. If BST is
+                * found before a Signature token this would speed up (at least a little
+                * bit) the processing of STR Transform.
+                */
+                if (doDebug) {
+                    log.debug("Unknown Element: " + elem.getLocalName() + " " + elem.getNamespaceURI());
+                }
+            }
+        }
+        if (tlog.isDebugEnabled()) {
+            t2 = System.currentTimeMillis();
+            tlog.debug("processHeader: total " + (t2 - t0) +
+                    ", prepare " + (t1 - t0) +
+                    ", handle " + (t2 - t1));
+        }
+        return returnResults;
+    }
+}
diff --git a/src/org/apache/ws/security/WSSecurityEngineResult.java b/src/org/apache/ws/security/WSSecurityEngineResult.java
new file mode 100644
index 0000000..2ad4de1
--- /dev/null
+++ b/src/org/apache/ws/security/WSSecurityEngineResult.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright  2003-2006 The Apache Software Foundation, or their licensors, as
+ * appropriate.
+ *
+ *  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.apache.ws.security;
+
+import org.apache.ws.security.message.token.SignatureConfirmation;
+import org.apache.ws.security.message.token.Timestamp;
+import org.opensaml.SAMLAssertion;
+
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.Set;
+
+/**
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de)
+ */
+public class WSSecurityEngineResult {
+
+    private int action;
+    private Principal principal;
+    private X509Certificate cert;
+    private SAMLAssertion assertion;
+    private Timestamp timestamp;
+    private Set signedElements;
+    private byte[] signatureValue = null;
+    private SignatureConfirmation sigConf = null;
+
+    public WSSecurityEngineResult(int act, SAMLAssertion ass) {
+        principal = null;
+        cert = null;
+        action = act;
+        assertion = ass;
+    }
+
+    public WSSecurityEngineResult(int act, Principal princ,
+            X509Certificate certificate, Set elements, byte[] sv) {
+        principal = princ;
+        action = act;
+        cert = certificate;
+        signedElements = elements;
+        signatureValue = sv;
+    }
+
+    public WSSecurityEngineResult(int act, Timestamp tstamp) {
+        action = act;
+        timestamp = tstamp;
+    }
+
+    public WSSecurityEngineResult(int act, SignatureConfirmation sc) {
+        action = act;
+        sigConf = sc;
+    }
+    /**
+     * @return the actions vector. These actions were performed by the the
+     *         security engine.
+     */
+    public int getAction() {
+        return action;
+    }
+
+    /**
+     * @return the principals found if UsernameToken or Signature
+     *         processing were done
+     */
+    public Principal getPrincipal() {
+        return principal;
+    }
+
+    /**
+     * @return the Certificate found if Signature
+     *         processing were done
+     */
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+
+    /**
+     * @return Returns the assertion.
+     */
+    public SAMLAssertion getAssertion() {
+        return assertion;
+    }
+
+    /**
+     * @return the timestamp found
+     */
+    public Timestamp getTimestamp() {
+        return timestamp;
+    }
+
+    /**
+     * @return Returns the signedElements.
+     */
+    public Set getSignedElements() {
+        return signedElements;
+    }
+
+    /**
+     * @return Returns the signatureValue.
+     */
+    public byte[] getSignatureValue() {
+        return signatureValue;
+    }
+
+    /**
+     * @return Returns the sigConf.
+     */
+    public SignatureConfirmation getSigConf() {
+        return sigConf;
+    }
+
+    /**
+     * @param signatureValue The signatureValue to set.
+     */
+    public void setSignatureValue(byte[] signatureValue) {
+        this.signatureValue = signatureValue;
+    }
+    
+}
diff --git a/src/org/apache/ws/security/WSSecurityException.java b/src/org/apache/ws/security/WSSecurityException.java
new file mode 100644
index 0000000..258e010
--- /dev/null
+++ b/src/org/apache/ws/security/WSSecurityException.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import java.rmi.RemoteException;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Exception class for WS-Security.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class WSSecurityException extends RemoteException {
+    public static final int FAILURE = 0;
+    public static final int UNSUPPORTED_SECURITY_TOKEN = 1;
+    public static final int UNSUPPORTED_ALGORITHM = 2;
+    public static final int INVALID_SECURITY = 3;
+    public static final int INVALID_SECURITY_TOKEN = 4;
+    public static final int FAILED_AUTHENTICATION = 5;
+    public static final int FAILED_CHECK = 6;
+    public static final int SECURITY_TOKEN_UNAVAILABLE = 7;
+    public static final int FAILED_ENC_DEC = 8;
+    public static final int FAILED_SIGNATURE = 9;
+    private static ResourceBundle resources;
+
+    static {
+        try {
+            resources = ResourceBundle.getBundle("org.apache.ws.security.errors");
+        } catch (MissingResourceException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    private int errorCode;
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param args
+     * @param exception
+     */
+    public WSSecurityException(int errorCode, String msgId, Object[] args, Throwable exception) {
+        super(getMessage(errorCode, msgId, args), exception);
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param args
+     */
+    public WSSecurityException(int errorCode, String msgId, Object[] args) {
+        super(getMessage(errorCode, msgId, args));
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     */
+    public WSSecurityException(int errorCode, String msgId) {
+        this(errorCode, msgId, null);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     */
+    public WSSecurityException(int errorCode) {
+        this(errorCode, null, null);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorMessage
+     */
+    public WSSecurityException(String errorMessage) {
+        super(errorMessage);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorMessage
+     */
+    public WSSecurityException(String errorMessage, Throwable t) {
+        super(errorMessage, t);
+    }
+
+    /**
+     * Get the error code.
+     * <p/>
+     *
+     * @return error code of this exception See values above.
+     */
+    public int getErrorCode() {
+        return this.errorCode;
+    }
+
+    /**
+     * get the message from resource bundle.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param args
+     * @return the message translated from the property (message) file.
+     */
+    private static String getMessage(int errorCode, String msgId, Object[] args) {
+        String msg = null;
+        try {
+            msg = resources.getString(String.valueOf(errorCode));
+            if (msgId != null) {
+                return msg += (" (" + MessageFormat.format(resources.getString(msgId), args) + ")");
+            }
+        } catch (MissingResourceException e) {
+            throw new RuntimeException("Undefined '" + msgId + "' resource property");
+        }
+        return msg;
+    }
+}
diff --git a/src/org/apache/ws/security/WSUsernameTokenPrincipal.java b/src/org/apache/ws/security/WSUsernameTokenPrincipal.java
new file mode 100644
index 0000000..bc165c3
--- /dev/null
+++ b/src/org/apache/ws/security/WSUsernameTokenPrincipal.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security;
+
+import java.security.Principal;
+
+/**
+ * This class implements the <code>Principal</code> interface and
+ * represents a UsernameToken user. 
+ * <p/>In addition to the principal's name
+ * this principal object also conatins the nonce and created time of the
+ * UsernameToken (refer to the OASIS WS Security specification, UsernameToken
+ * profile). These values are set only if the password of UsernameToken was of
+ * type <code>PasswordDigest</code>.
+ * <p/>Furthermore the password type is
+ * provided to the application. The password type is the string of the type
+ * attribute of the password element inside the username token. Refer to the
+ * OASIS WSS specification for predefined password types. <p/>The
+ * <code>equals()</code> method use the prinicipal's name only and does not
+ * compare nonce or created time. 
+ * <p/>Modeled according to the example provided
+ * by JAAS documentation 
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com).
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com).
+ * @see java.security.Principal
+ * @see javax.security.auth.Subject
+ */
+public class WSUsernameTokenPrincipal implements Principal, java.io.Serializable {
+
+    /**
+     * @serial
+     */
+    private String name = null;
+    private String nonce = null;
+    private String password = null;
+    private String createdTime = null;
+    private String passwordType = null;
+    private boolean digest = false;
+
+    /**
+     * Create a WSUsernameTokenPrincipal with a WSUsernameToken username.
+     * <p/>
+     *
+     * @param name the WSUsernameToken username for this user.
+     * @throws NullPointerException if the <code>name</code>
+     *                              is <code>null</code>.
+     */
+    public WSUsernameTokenPrincipal(String name, boolean digest) {
+        if (name == null)
+            throw new NullPointerException("illegal null input");
+        this.name = name;
+        this.digest = digest;
+    }
+
+    /**
+     * Return the WSUsernameToken username for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @return the WSUsernameToken username for this <code>WSUsernameTokenPrincipal</code>
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Return the WSUsernameToken password type for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @return true if the password type was <code>PassowrdDigest</code>
+     */
+    public boolean isPasswordDigest() {
+        return digest;
+    }
+
+    /**
+     * Set the WSUsernameToken password for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @param password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * Return the WSUsernameToken password for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @return the WSUsernameToken password for this <code>WSUsernameTokenPrincipal</code>
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * Set the WSUsernameToken nonce for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @param nonce
+     */
+    public void setNonce(String nonce) {
+        this.nonce = nonce;
+    }
+
+    /**
+     * Return the WSUsernameToken nonce for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @return the WSUsernameToken nonce for this <code>WSUsernameTokenPrincipal</code>
+     */
+    public String getNonce() {
+        return nonce;
+    }
+
+    /**
+     * Set the WSUsernameToken created time for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     *
+     * @param createdTime
+     */
+    public void setCreatedTime(String createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    /**
+     * Return the WSUsernameToken created time for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     *
+     * @return the WSUsernameToken created time for this <code>WSUsernameTokenPrincipal</code>
+     */
+    public String getCreatedTime() {
+        return createdTime;
+    }
+
+    /**
+     * Return a string representation of this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     *
+     * @return a string representation of this <code>WSUsernameTokenPrincipal</code>.
+     */
+    public String toString() {
+        return ("WSUsernameTokenPrincipal:  " + name);
+    }
+
+	/**
+	 * @return Returns the passwordType.
+	 */
+	public String getPasswordType() {
+		return passwordType;
+	}
+	/**
+	 * @param passwordType The passwordType to set.
+	 */
+	public void setPasswordType(String passwordType) {
+		this.passwordType = passwordType;
+	}
+    /**
+     * Compares the specified Object with this <code>WSUsernameTokenPrincipal</code>
+     * for equality.  Returns true if the given object is also a
+     * <code>WSUsernameTokenPrincipal</code> and the two WSUsernameTokenPrincipals
+     * have the same username.
+     * <p/>
+     * <p/>
+     *
+     * @param o Object to be compared for equality with this
+     *          <code>WSUsernameTokenPrincipal</code>.
+     * @return true if the specified Object is equal equal to this
+     *         <code>WSUsernameTokenPrincipal</code>.
+     */
+    public boolean equals(Object o) {
+        if (o == null)
+            return false;
+        if (this == o)
+            return true;
+        if (!(o instanceof WSUsernameTokenPrincipal))
+            return false;
+        WSUsernameTokenPrincipal that = (WSUsernameTokenPrincipal) o;
+        if (this.getName().equals(that.getName()))
+            return true;
+        return false;
+    }
+
+    /**
+     * Return a hash code for this <code>WSUsernameTokenPrincipal</code>.
+     * <p/>
+     * <p/>
+     *
+     * @return a hash code for this <code>WSUsernameTokenPrincipal</code>.
+     */
+    public int hashCode() {
+        return name.hashCode();
+    }
+}
diff --git a/src/org/apache/ws/security/action/Action.java b/src/org/apache/ws/security/action/Action.java
new file mode 100644
index 0000000..fe3408f
--- /dev/null
+++ b/src/org/apache/ws/security/action/Action.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.w3c.dom.Document;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.WSSecurityException;

+

+/**

+ * Interface for all actions

+ */

+public interface Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc,

+            RequestData reqData) throws WSSecurityException;

+}

diff --git a/src/org/apache/ws/security/action/EncryptionAction.java b/src/org/apache/ws/security/action/EncryptionAction.java
new file mode 100644
index 0000000..2f04187
--- /dev/null
+++ b/src/org/apache/ws/security/action/EncryptionAction.java
@@ -0,0 +1,68 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.w3c.dom.Document;

+

+public class EncryptionAction implements Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        WSSecEncrypt wsEncrypt = new WSSecEncrypt();

+        wsEncrypt.setWsConfig(reqData.getWssConfig());

+

+        if (reqData.getEncKeyId() != 0) {

+            wsEncrypt.setKeyIdentifierType(reqData.getEncKeyId());

+        }

+        if (reqData.getEncKeyId() == WSConstants.EMBEDDED_KEYNAME) {

+            String encKeyName 

+		= handler.getString(WSHandlerConstants.ENC_KEY_NAME,

+				    reqData.getMsgContext());

+            wsEncrypt.setEmbeddedKeyName(encKeyName);

+            byte[] embeddedKey =

+                    handler.getPassword(reqData.getEncUser(),

+                            actionToDo,

+                            WSHandlerConstants.ENC_CALLBACK_CLASS,

+                            WSHandlerConstants.ENC_CALLBACK_REF, reqData)

+                            .getKey();

+            wsEncrypt.setKey(embeddedKey);

+        }

+        if (reqData.getEncSymmAlgo() != null) {

+            wsEncrypt.setSymmetricEncAlgorithm(reqData.getEncSymmAlgo());

+        }

+        if (reqData.getEncKeyTransport() != null) {

+            wsEncrypt.setKeyEnc(reqData.getEncKeyTransport());

+        }

+        wsEncrypt.setUserInfo(reqData.getEncUser());

+        wsEncrypt.setUseThisCert(reqData.getEncCert());

+        if (reqData.getEncryptParts().size() > 0) {

+            wsEncrypt.setParts(reqData.getEncryptParts());

+        }

+        try {

+            wsEncrypt.build(doc, reqData.getEncCrypto(), reqData.getSecHeader());

+        } catch (WSSecurityException e) {

+            throw new WSSecurityException("WSHandler: Encryption: error during message processing"

+                    + e);

+        }

+    }

+}

diff --git a/src/org/apache/ws/security/action/SAMLTokenSignedAction.java b/src/org/apache/ws/security/action/SAMLTokenSignedAction.java
new file mode 100644
index 0000000..7a68c8f
--- /dev/null
+++ b/src/org/apache/ws/security/action/SAMLTokenSignedAction.java
@@ -0,0 +1,107 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.saml.SAMLIssuer;

+import org.apache.ws.security.saml.SAMLIssuerFactory;

+import org.apache.ws.security.saml.WSSecSignatureSAML;

+import org.opensaml.SAMLAssertion;

+import org.w3c.dom.Document;

+

+public class SAMLTokenSignedAction implements Action {

+    private static Log log = LogFactory.getLog(SAMLTokenSignedAction.class.getName());

+

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        Crypto crypto = null;

+        /*

+        * it is possible and legal that we do not have a signature

+        * crypto here - thus ignore the exception. This is usually

+        * the case for the SAML option "sender vouches". In this case

+        * no user crypto is required.

+        */

+        try {

+            crypto = handler.loadSignatureCrypto(reqData);

+        } catch (Throwable t){

+        }

+

+        SAMLIssuer saml = loadSamlIssuer(handler, reqData);

+        saml.setUsername(reqData.getUsername());

+        saml.setUserCrypto(crypto);

+        saml.setInstanceDoc(doc);

+

+        SAMLAssertion assertion = saml.newAssertion();

+        if (assertion == null) {

+            throw new WSSecurityException("WSHandler: Signed SAML: no SAML token received");

+        }

+        String issuerKeyName = null;

+        String issuerKeyPW = null;

+        Crypto issuerCrypto = null;

+

+        WSSecSignatureSAML wsSign = new WSSecSignatureSAML();

+        wsSign.setWsConfig(reqData.getWssConfig());

+

+        String password = null;

+        if (saml.isSenderVouches()) {

+            issuerKeyName = saml.getIssuerKeyName();

+            issuerKeyPW = saml.getIssuerKeyPassword();

+            issuerCrypto = saml.getIssuerCrypto();

+        } else {

+            password =

+                    handler.getPassword(reqData.getUsername(),

+                            actionToDo,

+                            WSHandlerConstants.PW_CALLBACK_CLASS,

+                            WSHandlerConstants.PW_CALLBACK_REF, reqData)

+                            .getPassword();

+            wsSign.setUserInfo(reqData.getUsername(), password);

+        }

+        if (reqData.getSigKeyId() != 0) {

+            wsSign.setKeyIdentifierType(reqData.getSigKeyId());

+        }

+        try {

+            wsSign.build(

+                    doc,

+                    crypto,

+                    assertion,

+                    issuerCrypto,

+                    issuerKeyName,

+                    issuerKeyPW,

+                    reqData.getSecHeader());

+            reqData.getSignatureValues().add(wsSign.getSignatureValue());

+        } catch (WSSecurityException e) {

+            throw new WSSecurityException("WSHandler: Signed SAML: error during message processing"

+                    + e);

+        }

+    }

+

+    protected SAMLIssuer loadSamlIssuer(WSHandler handler, 

+					RequestData reqData) {

+        String samlPropFile 

+	    = handler.getString(WSHandlerConstants.SAML_PROP_FILE,

+				reqData.getMsgContext());

+        return SAMLIssuerFactory.getInstance(samlPropFile);

+    }

+

+}

diff --git a/src/org/apache/ws/security/action/SAMLTokenUnsignedAction.java b/src/org/apache/ws/security/action/SAMLTokenUnsignedAction.java
new file mode 100644
index 0000000..0a42179
--- /dev/null
+++ b/src/org/apache/ws/security/action/SAMLTokenUnsignedAction.java
@@ -0,0 +1,42 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.message.WSSecSAMLToken;

+import org.apache.ws.security.saml.SAMLIssuer;

+import org.opensaml.SAMLAssertion;

+import org.w3c.dom.Document;

+

+public class SAMLTokenUnsignedAction extends SAMLTokenSignedAction {

+

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        WSSecSAMLToken builder = new WSSecSAMLToken();

+        builder.setWsConfig(reqData.getWssConfig());

+

+        SAMLIssuer saml = loadSamlIssuer(handler, reqData);

+        saml.setUsername(reqData.getUsername());

+        SAMLAssertion assertion = saml.newAssertion();

+

+        // add the SAMLAssertion Token to the SOAP Enevelope

+        builder.build(doc, assertion, reqData.getSecHeader());

+    }

+}

diff --git a/src/org/apache/ws/security/action/SignatureAction.java b/src/org/apache/ws/security/action/SignatureAction.java
new file mode 100644
index 0000000..f904eac
--- /dev/null
+++ b/src/org/apache/ws/security/action/SignatureAction.java
@@ -0,0 +1,61 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.message.WSSecSignature;

+import org.w3c.dom.Document;

+

+public class SignatureAction implements Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        String password;

+        password =

+                handler.getPassword(reqData.getUsername(),

+                        actionToDo,

+                        WSHandlerConstants.PW_CALLBACK_CLASS,

+                        WSHandlerConstants.PW_CALLBACK_REF, reqData)

+                        .getPassword();

+

+        WSSecSignature wsSign = new WSSecSignature();

+        wsSign.setWsConfig(reqData.getWssConfig());

+

+        if (reqData.getSigKeyId() != 0) {

+            wsSign.setKeyIdentifierType(reqData.getSigKeyId());

+        }

+        if (reqData.getSigAlgorithm() != null) {

+            wsSign.setSignatureAlgorithm(reqData.getSigAlgorithm());

+        }

+

+        wsSign.setUserInfo(reqData.getUsername(), password);

+        if (reqData.getSignatureParts().size() > 0) {

+            wsSign.setParts(reqData.getSignatureParts());

+        }

+

+        try {

+            wsSign.build(doc, reqData.getSigCrypto(), reqData.getSecHeader());

+            reqData.getSignatureValues().add(wsSign.getSignatureValue());

+        } catch (WSSecurityException e) {

+            throw new WSSecurityException("WSHandler: Signature: error during message procesing" + e);

+        }

+    }

+

+}

diff --git a/src/org/apache/ws/security/action/SignatureConfirmationAction.java b/src/org/apache/ws/security/action/SignatureConfirmationAction.java
new file mode 100644
index 0000000..d96cdda
--- /dev/null
+++ b/src/org/apache/ws/security/action/SignatureConfirmationAction.java
@@ -0,0 +1,86 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.handler.WSHandlerResult;

+import org.apache.ws.security.message.WSSecSignatureConfirmation;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+

+import java.util.Vector;

+

+public class SignatureConfirmationAction implements Action {

+    protected static Log log = LogFactory.getLog(WSHandler.class.getName());

+

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Perform Signature confirmation");

+        }

+

+        Vector results = (Vector) handler.getProperty(reqData.getMsgContext(),

+                WSHandlerConstants.RECV_RESULTS);

+        /*

+         * loop over all results gathered by all handlers in the chain. For each

+         * handler result get the various actions. After that loop we have all

+         * signature results in the signatureActions vector

+         */

+        Vector signatureActions = new Vector();

+        for (int i = 0; i < results.size(); i++) {

+            WSHandlerResult wshResult = (WSHandlerResult) results.get(i);

+

+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),

+                    WSConstants.SIGN, signatureActions);

+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),

+                    WSConstants.ST_SIGNED, signatureActions);

+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),

+                    WSConstants.UT_SIGN, signatureActions);

+        }

+        Vector signatureParts = reqData.getSignatureParts();

+        // prepare a SignatureConfirmation token

+        WSSecSignatureConfirmation wsc = new WSSecSignatureConfirmation();

+        int idHash = wsc.hashCode();

+        if (signatureActions.size() > 0) {

+            if (log.isDebugEnabled()) {

+                log.debug("Signature Confirmation: number of Signature results: "

+                        + signatureActions.size());

+            }

+            for (int i = 0; i < signatureActions.size(); i++) {

+                WSSecurityEngineResult wsr = (WSSecurityEngineResult) signatureActions

+                        .get(i);

+                byte[] sigVal = wsr.getSignatureValue();

+                wsc.build(doc, sigVal, reqData.getSecHeader());

+                signatureParts.add(new WSEncryptionPart(wsc.getId()));

+            }

+        } else {

+            wsc.build(doc, null, reqData.getSecHeader());

+            signatureParts.add(new WSEncryptionPart(wsc.getId()));

+        }

+        handler.setProperty(reqData.getMsgContext(), WSHandlerConstants.SIG_CONF_DONE,

+                WSHandler.DONE);

+    }

+}

diff --git a/src/org/apache/ws/security/action/TimestampAction.java b/src/org/apache/ws/security/action/TimestampAction.java
new file mode 100644
index 0000000..622c4dd
--- /dev/null
+++ b/src/org/apache/ws/security/action/TimestampAction.java
@@ -0,0 +1,36 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.message.WSSecTimestamp;

+import org.w3c.dom.Document;

+

+public class TimestampAction implements Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        WSSecTimestamp timeStampBuilder =

+                new WSSecTimestamp();

+        timeStampBuilder.setWsConfig(reqData.getWssConfig());

+        timeStampBuilder.setTimeToLive(handler.decodeTimeToLive(reqData));

+        // add the Timestamp to the SOAP Enevelope

+        timeStampBuilder.build(doc, reqData.getSecHeader());

+    }

+}

diff --git a/src/org/apache/ws/security/action/UsernameTokenAction.java b/src/org/apache/ws/security/action/UsernameTokenAction.java
new file mode 100644
index 0000000..2f464c5
--- /dev/null
+++ b/src/org/apache/ws/security/action/UsernameTokenAction.java
@@ -0,0 +1,57 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.message.WSSecUsernameToken;

+import org.w3c.dom.Document;

+

+public class UsernameTokenAction implements Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        String password;

+        password =

+                handler.getPassword(reqData.getUsername(),

+                        actionToDo,

+                        WSHandlerConstants.PW_CALLBACK_CLASS,

+                        WSHandlerConstants.PW_CALLBACK_REF, reqData)

+                        .getPassword();

+

+        WSSecUsernameToken builder = new WSSecUsernameToken();

+        builder.setWsConfig(reqData.getWssConfig());

+        builder.setPasswordType(reqData.getPwType());

+        builder.setUserInfo(reqData.getUsername(), password);

+

+        if (reqData.getUtElements() != null && reqData.getUtElements().length > 0) {

+            for (int j = 0; j < reqData.getUtElements().length; j++) {

+                reqData.getUtElements()[j].trim();

+                if (reqData.getUtElements()[j].equals("Nonce")) {

+                    builder.addNonce();

+                }

+                if (reqData.getUtElements()[j].equals("Created")) {

+                    builder.addCreated();

+                }

+                reqData.getUtElements()[j] = null;

+            }

+        }

+        builder.build(doc, reqData.getSecHeader());        

+    }

+}

diff --git a/src/org/apache/ws/security/action/UsernameTokenSignedAction.java b/src/org/apache/ws/security/action/UsernameTokenSignedAction.java
new file mode 100644
index 0000000..76cc10a
--- /dev/null
+++ b/src/org/apache/ws/security/action/UsernameTokenSignedAction.java
@@ -0,0 +1,64 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.action;

+

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.handler.RequestData;

+import org.apache.ws.security.handler.WSHandler;

+import org.apache.ws.security.handler.WSHandlerConstants;

+import org.apache.ws.security.message.WSSecUsernameToken;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.xml.security.signature.XMLSignature;

+import org.w3c.dom.Document;

+

+public class UsernameTokenSignedAction implements Action {

+    public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)

+            throws WSSecurityException {

+        String password;

+        password = handler.getPassword(reqData.getUsername(), actionToDo,

+                WSHandlerConstants.PW_CALLBACK_CLASS,

+                WSHandlerConstants.PW_CALLBACK_REF, reqData).getPassword();

+

+        WSSecUsernameToken builder = new WSSecUsernameToken();

+        builder.setWsConfig(reqData.getWssConfig());

+        builder.setPasswordType(WSConstants.PASSWORD_TEXT);

+        builder.setUserInfo(reqData.getUsername(), password);

+        builder.addCreated();

+        builder.addNonce();

+        builder.prepare(doc);

+        

+        WSSecSignature sign = new WSSecSignature();

+        sign.setWsConfig(reqData.getWssConfig());

+

+        if (reqData.getSignatureParts().size() > 0) {

+            sign.setParts(reqData.getSignatureParts());

+        }

+        sign.setUsernameToken(builder);

+        sign.setKeyIdentifierType(WSConstants.UT_SIGNING);

+        sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

+        try {

+            sign.build(doc, null, reqData.getSecHeader());

+            reqData.getSignatureValues().add(sign.getSignatureValue());

+        } catch (WSSecurityException e) {

+            throw new WSSecurityException("WSHandler: Error during Signatur with UsernameToken secret"

+                    + e);

+        }

+        builder.prependToHeader(reqData.getSecHeader());

+    }

+}

diff --git a/src/org/apache/ws/security/components/crypto/AbstractCrypto.java b/src/org/apache/ws/security/components/crypto/AbstractCrypto.java
new file mode 100644
index 0000000..eb1d20e
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/AbstractCrypto.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.components.crypto;
+
+import org.apache.commons.discovery.Resource;
+import org.apache.commons.discovery.ResourceIterator;
+import org.apache.commons.discovery.jdk.JDKHooks;
+import org.apache.commons.discovery.resource.DiscoverResources;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dims
+ * Date: Sep 15, 2005
+ * Time: 9:50:40 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class AbstractCrypto implements Crypto {
+    private static Log log = LogFactory.getLog(AbstractCrypto.class);
+    protected static CertificateFactory certFact;
+    protected Properties properties = null;
+    protected KeyStore keystore = null;
+    static String SKI_OID = "2.5.29.14";
+
+    /**
+     * Constructor
+     *
+     * @param properties
+     */
+    public AbstractCrypto(Properties properties) throws CredentialException, IOException {
+    	this(properties,AbstractCrypto.class.getClassLoader());
+    }
+
+    /**
+     * This allows providing a custom class loader to load the resources, etc
+     * @param properties
+     * @param loader
+     * @throws CredentialException
+     * @throws IOException
+     */
+    public AbstractCrypto(Properties properties, ClassLoader loader) throws CredentialException, IOException {
+        /*
+        * if no properties .. just return an instance, the rest will be
+        * done later or this instance is just used to handle certificate
+        * conversions in this implementatio
+        */
+        if (properties == null) {
+            return;
+        }
+        this.properties = properties;
+        String location = this.properties.getProperty("org.apache.ws.security.crypto.merlin.file");
+        InputStream is = null;
+
+        /**
+         * Look for the keystore in classpaths
+         */
+        DiscoverResources disc = new DiscoverResources();
+        disc.addClassLoader(JDKHooks.getJDKHooks().getThreadContextClassLoader());
+        disc.addClassLoader(loader);
+        ResourceIterator iterator = disc.findResources(location);
+        if (iterator.hasNext()) {
+            Resource resource = iterator.nextResource();
+            is = resource.getResourceAsStream();
+        }
+
+        /**
+         * If we don't find it, then look on the file system.
+         */
+        if (is == null) {
+            try {
+                is = new FileInputStream(location);
+            } catch (Exception e) {
+                throw new CredentialException(3, "proxyNotFound", new Object[]{location});
+            }
+        }
+
+        /**
+         * Load the keystore
+         */
+        try {
+            load(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    
+    /**
+     * Singleton certificate factory for this Crypto instance.
+     * <p/>
+     *
+     * @return Returns a <code>CertificateFactory</code> to construct
+     *         X509 certficates
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public synchronized CertificateFactory getCertificateFactory() throws WSSecurityException {
+        if (certFact == null) {
+            try {
+                String provider = properties.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
+                if (provider == null || provider.length() == 0) {
+                    certFact = CertificateFactory.getInstance("X.509");
+                } else {
+                    certFact = CertificateFactory.getInstance("X.509", provider);
+                }
+            } catch (CertificateException e) {
+                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                        "unsupportedCertType");
+            } catch (NoSuchProviderException e) {
+                throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                        "noSecProvider");
+            }
+        }
+        return certFact;
+    }
+
+    /**
+     * load a X509Certificate from the input stream.
+     * <p/>
+     *
+     * @param in The <code>InputStream</code> array containg the X509 data
+     * @return Returns a X509 certificate
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public X509Certificate loadCertificate(InputStream in) throws WSSecurityException {
+        X509Certificate cert = null;
+        try {
+            cert =
+                    (X509Certificate) getCertificateFactory().generateCertificate(in);
+        } catch (CertificateException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "parseError");
+        }
+        return cert;
+    }
+
+    /**
+     * Gets the private key identified by <code>alias</> and <code>password</code>.
+     * <p/>
+     *
+     * @param alias    The alias (<code>KeyStore</code>) of the key owner
+     * @param password The password needed to access the private key
+     * @return The private key
+     * @throws Exception
+     */
+    public PrivateKey getPrivateKey(String alias, String password) throws Exception {
+        if (alias == null) {
+            throw new Exception("alias is null");
+        }
+        boolean b = keystore.isKeyEntry(alias);
+        if (!b) {
+            log.error("Cannot find key for alias: " + alias);
+            throw new Exception("Cannot find key for alias: " + alias);
+        }
+        Key keyTmp = keystore.getKey(alias, password.toCharArray());
+        if (!(keyTmp instanceof PrivateKey)) {
+            throw new Exception("Key is not a private key, alias: " + alias);
+        }
+        return (PrivateKey) keyTmp;
+    }
+
+    private Vector splitAndTrim(String inString) {
+        X509NameTokenizer nmTokens = new X509NameTokenizer(inString);
+        Vector vr = new Vector();
+
+        while (nmTokens.hasMoreTokens()) {
+            vr.add(nmTokens.nextToken());
+        }
+        java.util.Collections.sort(vr);
+        return vr;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer The issuer's name for the certificate
+     * @return alias name of the certificate that matches the issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer)
+            throws WSSecurityException {
+        return getAliasForX509Cert(issuer, null, false);
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given serial number and
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the SerialNumber and Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer       The issuer's name for the certificate
+     * @param serialNumber The serial number of the certificate from the named issuer
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer, BigInteger serialNumber)
+            throws WSSecurityException {
+        return getAliasForX509Cert(issuer, serialNumber, true);
+    }
+
+    /*
+    * need to check if "getCertificateChain" also finds certificates that are
+    * used for enryption only, i.e. they may not be signed by a CA
+    * Otherwise we must define a restriction how to use certificate:
+    * each certificate must be signed by a CA or is a self signed Certificate
+    * (this should work as well).
+    * --- remains to be tested in several ways --
+    */
+    private String getAliasForX509Cert(String issuer, BigInteger serialNumber,
+                                       boolean useSerialNumber)
+            throws WSSecurityException {
+        Vector issuerRDN = splitAndTrim(issuer);
+        X509Certificate x509cert = null;
+        Vector certRDN = null;
+        Certificate cert = null;
+
+        try {
+            for (Enumeration e = keystore.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+                Certificate[] certs = keystore.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a  result.
+                    cert = keystore.getCertificate(alias);
+                    if (cert == null) {
+                        return null;
+                    }
+                } else {
+                    cert = certs[0];
+                }
+                if (!(cert instanceof X509Certificate)) {
+                    continue;
+                }
+                x509cert = (X509Certificate) cert;
+                if (!useSerialNumber ||
+                        useSerialNumber && x509cert.getSerialNumber().compareTo(serialNumber) == 0) {
+                    certRDN = splitAndTrim(x509cert.getIssuerDN().getName());
+                    if (certRDN.equals(issuerRDN)) {
+                        return alias;
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * SubjectKeyIdentifier.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * or certificate for each alias. Then the SKI for each user certificate
+     * is compared with the SKI parameter.
+     *
+     * @param skiBytes The SKI info bytes
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     * @throws org.apache.ws.security.WSSecurityException
+     *          if problems during keystore handling or wrong certificate (no SKI data)
+     */
+
+    public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException {
+        Certificate cert = null;
+        boolean found = false;
+
+        try {
+            for (Enumeration e = keystore.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+                Certificate[] certs = keystore.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a  result.
+                    cert = keystore.getCertificate(alias);
+                    if (cert == null) {
+                        return null;
+                    }
+                } else {
+                    cert = certs[0];
+                }
+                if (!(cert instanceof X509Certificate)) {
+                    continue;
+                }
+                byte[] data = getSKIBytesFromCert((X509Certificate) cert);
+                if (data.length != skiBytes.length) {
+                    continue;
+                }
+                if (Arrays.equals(data, skiBytes)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Return a X509 Certificate alias in the keystore according to a given Certificate
+     * <p/>
+     *
+     * @param cert The certificate to lookup
+     * @return alias name of the certificate that matches the given certificate
+     *         or null if no such certificate was found.
+     */
+
+/*
+     * See comment above
+     */
+    public String getAliasForX509Cert(Certificate cert) throws WSSecurityException {
+        try {
+            String alias = keystore.getCertificateAlias(cert);
+            if (alias != null)
+                return alias;
+            // Use brute force search
+            Enumeration e = keystore.aliases();
+            while (e.hasMoreElements()) {
+                alias = (String) e.nextElement();
+                X509Certificate cert2 = (X509Certificate) keystore.getCertificate(alias);
+                if (cert2.equals(cert)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * Retrieves the alias name of the default certificate which has been
+     * specified as a property. This should be the certificate that is used for
+     * signature and encryption. This alias corresponds to the certificate that
+     * should be used whenever KeyInfo is not poresent in a signed or
+     * an encrypted message. May return null.
+     *
+     * @return alias name of the default X509 certificate
+     */
+    public String getDefaultX509Alias() {
+        if (properties == null) {
+            return null;
+        }
+        return properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias");
+    }
+
+    /**
+     * Gets the list of certificates for a given alias.
+     * <p/>
+     *
+     * @param alias Lookup certificate chain for this alias
+     * @return Array of X509 certificates for this alias name, or
+     *         null if this alias does not exist in the keystore
+     */
+    public X509Certificate[] getCertificates(String alias) throws WSSecurityException {
+        Certificate[] certs = null;
+        try {
+            certs = keystore.getCertificateChain(alias);
+            if (certs == null || certs.length == 0) {
+                // no cert chain, so lets check if getCertificate gives us a  result.
+                Certificate cert = keystore.getCertificate(alias);
+                if (cert == null) {
+                    return null;
+                }
+                certs = new Certificate[]{cert};
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        X509Certificate[] x509certs = new X509Certificate[certs.length];
+        for (int i = 0; i < certs.length; i++) {
+            x509certs[i] = (X509Certificate) certs[i];
+        }
+        return x509certs;
+    }
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * Thumbprint.
+     * <p/>
+     * The search gets all alias names of the keystore, then reads the certificate chain
+     * or certificate for each alias. Then the thumbprint for each user certificate
+     * is compared with the thumbprint parameter.
+     *
+     * @param thumb The SHA1 thumbprint info bytes
+     * @return alias name of the certificate that matches the thumbprint
+     *         or null if no such certificate was found.
+     * @throws org.apache.ws.security.WSSecurityException
+     *          if problems during keystore handling or wrong certificate
+     */
+
+    public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException {
+        Certificate cert = null;
+        MessageDigest sha = null;
+
+        try {
+            sha = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e1) {
+            throw new WSSecurityException(
+                    0,
+                    "noSHA1availabe");
+        }
+        try {
+            for (Enumeration e = keystore.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+                Certificate[] certs = keystore.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a  result.
+                    cert = keystore.getCertificate(alias);
+                    if (cert == null) {
+                        return null;
+                    }
+                } else {
+                    cert = certs[0];
+                }
+                if (!(cert instanceof X509Certificate)) {
+                    continue;
+                }
+                sha.reset();
+                try {
+                    sha.update(cert.getEncoded());
+                } catch (CertificateEncodingException e1) {
+                    throw new WSSecurityException(
+                            WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                            "encodeError");
+                }
+                byte[] data = sha.digest();
+
+                if (Arrays.equals(data, thumb)) {
+                    return alias;
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+        return null;
+    }
+
+    /**
+     * A Hook for subclasses to set the keystore without having to
+     * load it from an <code>InputStream</code>.
+     *
+     * @param ks existing keystore
+     */
+    public void setKeyStore(KeyStore ks) {
+        keystore = ks;
+    }
+
+    /**
+     * Loads the the keystore from an <code>InputStream </code>.
+     * <p/>
+     *
+     * @param input <code>InputStream</code> to read from
+     * @throws CredentialException
+     */
+    public void load(InputStream input) throws CredentialException {
+        if (input == null) {
+            throw new IllegalArgumentException("input stream cannot be null");
+        }
+        try {
+            String provider = properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.provider");
+            if (provider == null || provider.length() == 0) {
+                keystore = KeyStore.getInstance
+                        (properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type",
+                                KeyStore.getDefaultType()));
+            } else {
+                keystore = KeyStore.getInstance
+                        (properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.type",
+                                KeyStore.getDefaultType()), provider);
+            }
+            String password =
+                    properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.password",
+                            "security");
+            keystore.load(input, (password == null || password.length() == 0) ? new char[0] : password.toCharArray());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new CredentialException(3, "ioError00", e);
+        } catch (GeneralSecurityException e) {
+            e.printStackTrace();
+            throw new CredentialException(3, "secError00", e);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new CredentialException(-1, "error00", e);
+        }
+    }
+
+    /**
+     * Reads the SubjectKeyIdentifier information from the certificate.
+     * <p/>
+     * If the the certificate does not contain a SKI extension then
+     * try to compute the SKI according to RFC3280 using the
+     * SHA-1 hash value of the public key. The second method described
+     * in RFC3280 is not support. Also only RSA public keys are supported.
+     * If we cannot compute the SKI throw a WSSecurityException.
+     *
+     * @param cert The certificate to read SKI
+     * @return The byte array conating the binary SKI data
+     */
+    public byte[] getSKIBytesFromCert(X509Certificate cert)
+            throws WSSecurityException {
+        /*
+           * Gets the DER-encoded OCTET string for the extension value (extnValue)
+           * identified by the passed-in oid String. The oid string is represented
+           * by a set of positive whole numbers separated by periods.
+           */
+        byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);
+
+        if (cert.getVersion() < 3 || derEncodedValue == null) {
+            PublicKey key = cert.getPublicKey();
+            if (!(key instanceof RSAPublicKey)) {
+                throw new WSSecurityException(
+                        1,
+                        "noSKIHandling",
+                        new Object[]{"Support for RSA key only"});
+            }
+            byte[] encoded = key.getEncoded();
+            // remove 22-byte algorithm ID and header
+            byte[] value = new byte[encoded.length - 22];
+            System.arraycopy(encoded, 22, value, 0, value.length);
+            MessageDigest sha;
+            try {
+                sha = MessageDigest.getInstance("SHA-1");
+            } catch (NoSuchAlgorithmException ex) {
+                throw new WSSecurityException(
+                        1,
+                        "noSKIHandling",
+                        new Object[]{"Wrong certificate version (<3) and no SHA1 message digest availabe"});
+            }
+            sha.reset();
+            sha.update(value);
+            return sha.digest();
+        }
+
+        /**
+         * Strip away first four bytes from the DerValue (tag and length of
+         * ExtensionValue OCTET STRING and KeyIdentifier OCTET STRING)
+         */
+        byte abyte0[] = new byte[derEncodedValue.length - 4];
+
+        System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length);
+        return abyte0;
+    }
+
+    public KeyStore getKeyStore() {
+        return this.keystore;
+    }
+
+    /**
+     * Lookup X509 Certificates in the keystore according to a given DN of the subject of the certificate
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate (chain)
+     * for each alias. Then the DN of the certificate is compared with the parameters.
+     *
+     * @param subjectDN The DN of subject to look for in the keystore
+     * @return Vector with all alias of certificates with the same DN as given in the parameters
+     * @throws org.apache.ws.security.WSSecurityException
+     *
+     */
+    public String[] getAliasesForDN(String subjectDN) throws WSSecurityException {
+
+        // Store the aliases found
+        Vector aliases = new Vector();
+
+        Certificate cert = null;
+
+        // The DN to search the keystore for
+        Vector subjectRDN = splitAndTrim(subjectDN);
+
+        // Look at every certificate in the keystore
+        try {
+            for (Enumeration e = keystore.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+
+                Certificate[] certs = keystore.getCertificateChain(alias);
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us a  result.
+                    cert = keystore.getCertificate(alias);
+                    if (cert == null) {
+                        return null;
+                    }
+                    certs = new Certificate[]{cert};
+                } else {
+                    cert = certs[0];
+                }
+                if (cert instanceof X509Certificate) {
+                    Vector foundRDN = splitAndTrim(((X509Certificate) cert).getSubjectDN().getName());
+
+                    if (subjectRDN.equals(foundRDN)) {
+                        aliases.add(alias);
+                    }
+                }
+            }
+        } catch (KeyStoreException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "keystore");
+        }
+
+        // Convert the vector into an array
+        String[] result = new String[aliases.size()];
+        for (int i = 0; i < aliases.size(); i++)
+            result[i] = (String) aliases.elementAt(i);
+
+        return result;
+    }
+}
diff --git a/src/org/apache/ws/security/components/crypto/BouncyCastle.java b/src/org/apache/ws/security/components/crypto/BouncyCastle.java
new file mode 100644
index 0000000..3c90a67
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/BouncyCastle.java
@@ -0,0 +1,184 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.components.crypto;

+

+import org.apache.ws.security.WSSecurityException;

+

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.security.InvalidAlgorithmParameterException;

+import java.security.KeyStoreException;

+import java.security.NoSuchAlgorithmException;

+import java.security.cert.CertPath;

+import java.security.cert.CertPathValidator;

+import java.security.cert.CertPathValidatorException;

+import java.security.cert.CertificateEncodingException;

+import java.security.cert.CertificateException;

+import java.security.cert.CertificateFactory;

+import java.security.cert.PKIXParameters;

+import java.security.cert.X509Certificate;

+import java.util.Arrays;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Properties;

+import java.util.Vector;

+

+/**

+ * JDK1.4 based implementation of Crypto (uses keystore).

+ * <p/>

+ *

+ * @author Davanum Srinivas (dims@yahoo.com).

+ */

+public class BouncyCastle extends AbstractCrypto {

+

+    /**

+     * Constructor.

+     * <p/>

+     *

+     * @param properties

+     * @throws CredentialException

+     * @throws java.io.IOException

+     */

+    public BouncyCastle(Properties properties) throws CredentialException, IOException {

+        super(properties);

+    }

+

+    /**

+     * Construct an array of X509Certificate's from the byte array.

+     * <p/>

+     *

+     * @param data    The <code>byte</code> array containg the X509 data

+     * @param reverse If set the first certificate in input data will

+     *                the last in the array

+     * @return An array of X509 certificates, ordered according to

+     *         the reverse flag

+     * @throws org.apache.ws.security.WSSecurityException

+     *

+     */

+    public X509Certificate[] getX509Certificates(byte[] data, boolean reverse)

+            throws WSSecurityException {

+        InputStream in = new ByteArrayInputStream(data);

+        CertPath path = null;

+        try {

+            CertificateFactory factory = CertificateFactory.getInstance("X.509");

+            path = factory.generateCertPath(in);

+        } catch (CertificateException e) {

+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,

+                    "parseError");

+        }

+        List l = path.getCertificates();

+        X509Certificate[] certs = new X509Certificate[l.size()];

+        Iterator iterator = l.iterator();

+        for (int i = 0; i < l.size(); i++) {

+            certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator.next();

+        }

+        return certs;

+    }

+

+    /**

+     * get a byte array given an array of X509 certificates.

+     * <p/>

+     *

+     * @param reverse If set the first certificate in the array data will

+     *                the last in the byte array

+     * @param certs   The certificates to convert

+     * @return The byte array for the certficates ordered according

+     *         to the reverse flag

+     * @throws org.apache.ws.security.WSSecurityException

+     *

+     */

+    public byte[] getCertificateData(boolean reverse, X509Certificate[] certs)

+            throws WSSecurityException {

+        Vector list = new Vector();

+        for (int i = 0; i < certs.length; i++) {

+            if (reverse) {

+                list.insertElementAt(certs[i], 0);

+            } else {

+                list.add(certs[i]);

+            }

+        }

+        try {

+            CertificateFactory factory = CertificateFactory.getInstance("X.509");

+            CertPath path = factory.generateCertPath(list);

+            return path.getEncoded();

+        } catch (CertificateEncodingException e) {

+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,

+                    "encodeError");

+        } catch (CertificateException e) {

+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,

+                    "parseError");

+        }

+    }

+

+    /**

+     * Uses the CertPath API to validate a given certificate chain

+     *

+     * @param certs Certificate chain to validate

+     * @return true if the certificate chain is valid, false otherwise

+     * @throws org.apache.ws.security.WSSecurityException

+     *

+     */

+    public boolean validateCertPath(X509Certificate[] certs) throws WSSecurityException {

+

+        try {

+            // Generate cert path

+            List certList = Arrays.asList(certs);

+            CertificateFactory factory = CertificateFactory.getInstance("X.509");

+            CertPath path = factory.generateCertPath(certList);

+

+            // Use the certificates in the keystore as TrustAnchors

+            PKIXParameters param = new PKIXParameters(this.keystore);

+

+            // Do not check a revocation list

+            param.setRevocationEnabled(false);

+

+            // Verify the trust path using the above settings            

+            CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX");

+            certPathValidator.validate(path, param);

+        } catch (NoSuchAlgorithmException ex) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "certpath",

+                    new Object[]{ex.getMessage()},

+                    (Throwable) ex);

+        } catch (CertificateException ex) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "certpath",

+                    new Object[]{ex.getMessage()},

+                    (Throwable) ex);

+        } catch (InvalidAlgorithmParameterException ex) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "certpath",

+                    new Object[]{ex.getMessage()},

+                    (Throwable) ex);

+        } catch (KeyStoreException ex) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "certpath",

+                    new Object[]{ex.getMessage()},

+                    (Throwable) ex);

+        } catch (CertPathValidatorException ex) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "certpath",

+                    new Object[]{ex.getMessage()},

+                    (Throwable) ex);

+        }

+        return true;

+    }

+}

+

+

diff --git a/src/org/apache/ws/security/components/crypto/CredentialException.java b/src/org/apache/ws/security/components/crypto/CredentialException.java
new file mode 100644
index 0000000..4e10c1d
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/CredentialException.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.components.crypto;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * CredentialException.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class CredentialException extends Exception {
+    public static final int FAILURE = -1;
+    public static final int EXPIRED = 1;
+    public static final int DEFECTIVE = 2;
+    public static final int IO_ERROR = 3;
+    public static final int SEC_ERROR = 3;
+    private static ResourceBundle resources;
+    private int errorCode;
+
+    static {
+        try {
+            resources = ResourceBundle.getBundle("org.apache.ws.security.components.crypto.errors");
+        } catch (MissingResourceException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param root
+     */
+    public CredentialException(int errorCode, String msgId, Throwable root) {
+        this(errorCode, msgId, null, root);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param args
+     */
+    public CredentialException(int errorCode, String msgId, Object[] args) {
+        this(errorCode, msgId, args, null);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param errorCode
+     * @param msgId
+     * @param args
+     * @param root
+     */
+    public CredentialException(int errorCode, String msgId, Object[] args, Throwable root) {
+        super(getMessage(msgId, args) + (root == null ? "[]" : " Inner Exception: [" + root.getMessage() + "]"));
+        this.errorCode = -1;
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * get the error code.
+     * <p/>
+     *
+     * @return error code of this exception See values above.
+     */
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    /**
+     * get the actual message.
+     * <p/>
+     *
+     * @param msgId
+     * @param args
+     * @return the message translated from the property (message) file.
+     */
+    private static String getMessage(String msgId, Object[] args) {
+        try {
+            return MessageFormat.format(resources.getString(msgId), args);
+        } catch (MissingResourceException e) {
+            throw new RuntimeException("bad" + msgId);
+        }
+    }
+}
+
diff --git a/src/org/apache/ws/security/components/crypto/Crypto.java b/src/org/apache/ws/security/components/crypto/Crypto.java
new file mode 100644
index 0000000..406d842
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/Crypto.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.components.crypto;
+
+import org.apache.ws.security.WSSecurityException;
+
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+/**
+ * Crypto.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public interface Crypto {
+    /**
+     * load a X509Certificate from the input stream.
+     * <p/>
+     *
+     * @param in The <code>InputStream</code> array containg the X509 data
+     * @return An X509 certificate
+     * @throws WSSecurityException
+     */
+    X509Certificate loadCertificate(InputStream in) throws WSSecurityException;
+
+    /**
+     * Construct an array of X509Certificate's from the byte array.
+     * <p/>
+     *
+     * @param data    The <code>byte</code> array containg the X509 data
+     * @param reverse If set the first certificate in input data will
+     *                the last in the array
+     * @return An array of X509 certificates, ordered according to
+     *         the reverse flag
+     * @throws WSSecurityException
+     */
+    X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws WSSecurityException;
+
+    /**
+     * get a byte array given an array of X509 certificates.
+     * <p/>
+     *
+     * @param reverse If set the first certificate in the array data will
+     *                the last in the byte array
+     * @param certs   The certificates to convert
+     * @return The byte array for the certficates ordered according
+     *         to the reverse flag
+     * @throws WSSecurityException
+     */
+    byte[] getCertificateData(boolean reverse, X509Certificate[] certs) throws WSSecurityException;
+
+    /**
+     * Gets the private key identified by <code>alias</> and <code>password</code>.
+     * <p/>
+     *
+     * @param alias    The alias (<code>KeyStore</code>) of the key owner
+     * @param password The password needed to access the private key
+     * @return The private key
+     * @throws Exception
+     */
+    public PrivateKey getPrivateKey(String alias, String password) throws Exception;
+
+    /**
+     * get the list of certificates for a given alias. This method
+     * reads a new certificate chain and overwrites a previously
+     * stored certificate chain.
+     * <p/>
+     *
+     * @param alias Lookup certificate chain for this alias
+     * @return Array of X509 certificates for this alias name, or
+     *         null if this alias does not exist in the keystore
+     */
+    public X509Certificate[] getCertificates(String alias) throws WSSecurityException;
+
+    /**
+     * Return a X509 Certificate alias in the keystore according to a given Certificate
+     * <p/>
+     *
+     * @param cert The certificate to lookup
+     * @return alias name of the certificate that matches the given certificate
+     *         or null if no such certificate was found.
+     *         <p/>
+     *         See comment above
+     *         <p/>
+     *         See comment above
+     */
+    /*
+     * See comment above
+     */
+    public String getAliasForX509Cert(Certificate cert) throws WSSecurityException;
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer The issuer's name for the certificate
+     * @return alias name of the certificate that matches the issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer) throws WSSecurityException;
+
+    /**
+     * Search a X509 Certificate in the keystore according to a given serial number and
+     * the issuer of a Certficate.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * for each alias. Then the SerialNumber and Issuer fo each certificate of the chain
+     * is compared with the parameters.
+     *
+     * @param issuer       The issuer's name for the certificate
+     * @param serialNumber The serial number of the certificate from the named issuer
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(String issuer, BigInteger serialNumber) throws WSSecurityException;
+
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * SubjectKeyIdentifier.
+     * <p/>
+     * The search gets all alias names of the keystore and gets the certificate chain
+     * or certificate for each alias. Then the SKI for each user certificate
+     * is compared with the SKI parameter.
+     *
+     * @param skiBytes The SKI info bytes
+     * @return alias name of the certificate that matches serialNumber and issuer name
+     *         or null if no such certificate was found.
+     */
+    public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException;
+
+    /**
+     * Retrieves the alias name of the default certificate which has been
+     * specified as a property. This should be the certificate that is used for
+     * signature and encryption. This alias corresponds to the certificate that
+     * should be used whenever KeyInfo is not poresent in a signed or
+     * an encrypted message. May return null.
+     *
+     * @return alias name of the default X509 certificate.
+     */
+    public String getDefaultX509Alias();
+
+    /**
+     * Reads the SubjectKeyIdentifier information from the certificate.
+     * <p/>
+     *
+     * @param cert The certificate to read SKI
+     * @return The byte array conating the binary SKI data
+     */
+    public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException;
+ 
+    /**
+     * Lookup a X509 Certificate in the keystore according to a given
+     * Thumbprint.
+     * 
+     * The search gets all alias names of the keystore, then reads the certificate chain
+     * or certificate for each alias. Then the thumbprint for each user certificate
+     * is compared with the thumbprint parameter.
+     *
+     * @param thumb The SHA1 thumbprint info bytes
+     * @return alias name of the certificate that matches the thumbprint
+     *         or null if no such certificate was found.
+     * @throws WSSecurityException if problems during keystore handling or wrong certificate
+     */
+
+    public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException;
+ 
+    /**
+     * Gets the Keystore that was loaded by the underlying implementation
+     *
+     * @return the Keystore
+     */
+    public KeyStore getKeyStore();
+
+    /**
+     * Gets the CertificateFactory instantiated by the underlying implementation
+     *
+     * @return the CertificateFactory
+     * @throws WSSecurityException
+     */
+    public CertificateFactory getCertificateFactory() throws WSSecurityException;
+
+    /**
+     * Uses the CertPath API to validate a given certificate chain
+     * <p/>
+     *
+     * @param certs Certificate chain to validate
+     * @return true if the certificate chain is valid, false otherwise
+     * @throws WSSecurityException
+     */
+    public boolean validateCertPath(X509Certificate[] certs) throws WSSecurityException;
+
+    /**
+     * Lookup X509 Certificates in the keystore according to a given DN of the subject of the certificate
+     * <p/>
+     *
+     * @param subjectDN The DN of subject to look for in the keystore
+     * @return Vector with all alias of certificates with the same DN as given in the parameters
+     * @throws WSSecurityException
+     */
+    public String[] getAliasesForDN(String subjectDN) throws WSSecurityException;
+}
diff --git a/src/org/apache/ws/security/components/crypto/CryptoFactory.java b/src/org/apache/ws/security/components/crypto/CryptoFactory.java
new file mode 100644
index 0000000..0493fc3
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/CryptoFactory.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.components.crypto;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.util.Loader;
+
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * CryptoFactory.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public abstract class CryptoFactory {
+    private static Log log = LogFactory.getLog(CryptoFactory.class);
+    private static final String defaultCryptoClassName = "org.apache.ws.security.components.crypto.Merlin";
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of Crypto. This method uses the file
+     * <code>crypto.properties</code> to determine which implementation to
+     * use. Thus the property <code>org.apache.ws.security.crypto.provider</code>
+     * must define the classname of the Crypto implementation. The file
+     * may contain other property definitions as well. These properties are
+     * handed over to the  Crypto implementation. The file
+     * <code>crypto.properties</code> is loaded with the
+     * <code>Loader.getResource()</code> method.
+     * <p/>
+     *
+     * @return The cyrpto implementation was defined
+     */
+    public static Crypto getInstance() {
+        return getInstance("crypto.properties");
+    }
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of Crypto. The properties are handed over the the crypto
+     * implementation. The porperties can be <code>null</code>. It is depenend on the
+     * Crypto implementation how the initialization is done in this case.
+     * <p/>
+     *
+     * @param cryptoClassName This is the crypto implementation class. No default is
+     *                        provided here.
+     * @param properties      The Properties that are forwarded to the crypto implementaion.
+     *                        These properties are dependend on the crypto implementatin
+     * @return The cyrpto implementation or null if no cryptoClassName was defined
+     */
+    public static Crypto getInstance(String cryptoClassName, Properties properties) {
+        return loadClass(cryptoClassName, properties);
+    }
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of Crypto. This method uses the specifed filename
+     * to load a property file. This file shall use the property
+     * <code>org.apache.ws.security.crypto.provider</code>
+     * to define the classname of the Crypto implementation. The file
+     * may contain other property definitions as well. These properties are
+     * handed over to the Crypto implementation. The specified file
+     * is loaded with the <code>Loader.getResource()</code> method.
+     * <p/>
+     *
+     * @param propFilename The name of the property file to load
+     * @return The cyrpto implementation that was defined
+     */
+    public static Crypto getInstance(String propFilename) {
+        Properties properties = null;
+        String cryptoClassName = null;
+
+        // cryptoClassName = System.getProperty("org.apache.ws.security.crypto.provider");
+        if ((cryptoClassName == null) || (cryptoClassName.length() == 0)) {
+            properties = getProperties(propFilename);
+            // use the default Crypto implementation
+            cryptoClassName = properties.getProperty("org.apache.ws.security.crypto.provider",
+                    defaultCryptoClassName);
+        }
+        return loadClass(cryptoClassName, properties);
+    }    
+    
+    public static Crypto getInstance(String propFilename, ClassLoader customClassLoader) {
+        Properties properties = null;
+        String cryptoClassName = null;
+
+        // cryptoClassName = System.getProperty("org.apache.ws.security.crypto.provider");
+        if ((cryptoClassName == null) || (cryptoClassName.length() == 0)) {
+            properties = getProperties(propFilename,customClassLoader);
+            // use the default Crypto implementation
+            cryptoClassName = properties.getProperty("org.apache.ws.security.crypto.provider",
+                    defaultCryptoClassName);
+        }
+        return loadClass(cryptoClassName, properties,customClassLoader);
+    }
+
+    private static Crypto loadClass(String cryptoClassName, Properties properties) {
+    	return loadClass(cryptoClassName,properties,CryptoFactory.class.getClassLoader());
+    }
+
+    /**
+     * This allows loading the classes with a custom class loader  
+     * @param cryptoClassName
+     * @param properties
+     * @param loader
+     * @return
+     */
+    private static Crypto loadClass(String cryptoClassName, Properties properties, ClassLoader loader) {
+        Class cryptogenClass = null;
+        Crypto crypto = null;
+        try {
+            // instruct the class loader to load the crypto implementation
+            cryptogenClass = Loader.loadClass(loader, cryptoClassName);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(cryptoClassName + " Not Found");
+        }
+        log.debug("Using Crypto Engine [" + cryptoClassName + "]");
+        try {
+            Class[] classes = new Class[]{Properties.class,ClassLoader.class};
+            Constructor c = cryptogenClass.getConstructor(classes);
+            crypto = (Crypto) c.newInstance(new Object[]{properties,loader});
+            return crypto;
+        } catch (java.lang.Exception e) {
+            e.printStackTrace();
+            log.error("Unable to instantiate (1): " + cryptoClassName, e);
+        }
+        try {
+            // try to instantiate the Crypto subclass
+            crypto = (Crypto) cryptogenClass.newInstance();
+            return crypto;
+        } catch (java.lang.Exception e) {
+            e.printStackTrace();
+            log.error("Unable to instantiate (2): " + cryptoClassName, e);
+            throw new RuntimeException(cryptoClassName + " cannot create instance");
+        }
+    }
+    /**
+     * Gets the properties for crypto.
+     * The functions loads the property file via
+     * {@link Loader.getResource(String)}, thus the property file
+     * should be accesible via the classpath
+     *
+     * @param propFilename the properties file to load
+     * @return a <code>Properties</code> object loaded from the filename
+     */
+    private static Properties getProperties(String propFilename) {
+    	return getProperties(propFilename, CryptoFactory.class.getClassLoader());
+    }
+    
+    
+    /**
+     * This allows loading the resources with a custom class loader
+     * @param propFilename
+     * @param loader
+     * @return
+     */
+    private static Properties getProperties(String propFilename, ClassLoader loader) {
+        Properties properties = new Properties();
+        try {
+            URL url = Loader.getResource(loader, propFilename);
+            properties.load(url.openStream());
+        } catch (Exception e) {
+            log.debug("Cannot find crypto property file: " + propFilename);
+            throw new RuntimeException("CryptoFactory: Cannot load properties: " +
+                    propFilename);
+        }
+        return properties;
+    }
+
+}
+
diff --git a/src/org/apache/ws/security/components/crypto/Merlin.java b/src/org/apache/ws/security/components/crypto/Merlin.java
new file mode 100644
index 0000000..fe069f3
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/Merlin.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.components.crypto;
+
+import org.apache.ws.security.WSSecurityException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.PKIXParameters;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * JDK1.4 based implementation of Crypto (uses keystore).
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class Merlin extends AbstractCrypto {
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param properties
+     * @throws CredentialException
+     * @throws IOException
+     */
+    public Merlin(Properties properties) throws CredentialException, IOException {
+        super(properties);
+    }
+    
+    public Merlin(Properties properties, ClassLoader loader) throws CredentialException, IOException {
+    	super(properties,loader);
+    }
+
+    /**
+     * Construct an array of X509Certificate's from the byte array.
+     * <p/>
+     *
+     * @param data    The <code>byte</code> array containg the X509 data
+     * @param reverse If set the first certificate in input data will
+     *                the last in the array
+     * @return An array of X509 certificates, ordered according to
+     *         the reverse flag
+     * @throws WSSecurityException
+     */
+    public X509Certificate[] getX509Certificates(byte[] data, boolean reverse)
+            throws WSSecurityException {
+        InputStream in = new ByteArrayInputStream(data);
+        CertPath path = null;
+        try {
+            path = getCertificateFactory().generateCertPath(in);
+        } catch (CertificateException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "parseError");
+        }
+        List l = path.getCertificates();
+        X509Certificate[] certs = new X509Certificate[l.size()];
+        Iterator iterator = l.iterator();
+        for (int i = 0; i < l.size(); i++) {
+            certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate) iterator.next();
+        }
+        return certs;
+    }
+
+    /**
+     * get a byte array given an array of X509 certificates.
+     * <p/>
+     *
+     * @param reverse If set the first certificate in the array data will
+     *                the last in the byte array
+     * @param certs   The certificates to convert
+     * @return The byte array for the certficates ordered according
+     *         to the reverse flag
+     * @throws WSSecurityException
+     */
+    public byte[] getCertificateData(boolean reverse, X509Certificate[] certs)
+            throws WSSecurityException {
+        Vector list = new Vector();
+        for (int i = 0; i < certs.length; i++) {
+            if (reverse) {
+                list.insertElementAt(certs[i], 0);
+            } else {
+                list.add(certs[i]);
+            }
+        }
+        try {
+            CertPath path = getCertificateFactory().generateCertPath(list);
+            return path.getEncoded();
+        } catch (CertificateEncodingException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "encodeError");
+        } catch (CertificateException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "parseError");
+        }
+    }
+
+
+    /**
+     * Overridden because there's a bug in the base class where they don't use
+     * the provider variant for the certificate validator.
+     *
+     * @param certs
+     *            Certificate chain to validate
+     * @return true if the certificate chain is valid, false otherwise
+     * @throws WSSecurityException
+     */
+    public boolean validateCertPath(X509Certificate[] certs)
+                    throws WSSecurityException {
+		try {
+			// Generate cert path
+			java.util.List certList = java.util.Arrays.asList(certs);
+			CertPath path = this.getCertificateFactory().generateCertPath(
+							certList);
+
+			// Use the certificates in the keystore as TrustAnchors
+			PKIXParameters param = new PKIXParameters(this.keystore);
+
+			// Do not check a revocation list
+			param.setRevocationEnabled(false);
+
+			// Verify the trust path using the above settings
+			String provider = properties
+							.getProperty("org.apache.ws.security.crypto.merlin.cert.provider");
+			CertPathValidator certPathValidator;
+			if (provider == null || provider.length() == 0) {
+					certPathValidator = CertPathValidator.getInstance("PKIX");
+			} else {
+					certPathValidator = CertPathValidator.getInstance("PKIX",
+									provider);
+			}
+			certPathValidator.validate(path, param);
+		} catch (NoSuchProviderException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		} catch (NoSuchAlgorithmException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		} catch (CertificateException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		} catch (InvalidAlgorithmParameterException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		} catch (CertPathValidatorException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		} catch (KeyStoreException ex) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+								"certpath", new Object[] { ex.getMessage() },
+								(Throwable) ex);
+		}
+
+		return true;
+    }
+}
+
+
diff --git a/src/org/apache/ws/security/components/crypto/X509NameTokenizer.java b/src/org/apache/ws/security/components/crypto/X509NameTokenizer.java
new file mode 100644
index 0000000..2a0047d
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/X509NameTokenizer.java
@@ -0,0 +1,67 @@
+/*
+ * This source is a plain copy from bouncycastle software.
+ * Thus:
+ * Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+ */
+package org.apache.ws.security.components.crypto;
+
+/**
+ * class for breaking up an X500 Name into it's component tokens, ala
+ * java.util.StringTokenizer. We need this class as some of the
+ * lightweight Java environment don't support classes like
+ * StringTokenizer.
+ */
+public class X509NameTokenizer {
+    private String oid;
+    private int index;
+    private StringBuffer buf = new StringBuffer();
+
+    public X509NameTokenizer(String oid) {
+        this.oid = oid;
+        this.index = -1;
+    }
+
+    public boolean hasMoreTokens() {
+        return (index != oid.length());
+    }
+
+    public String nextToken() {
+        if (index == oid.length()) {
+            return null;
+        }
+
+        int end = index + 1;
+        boolean quoted = false;
+        boolean escaped = false;
+
+        buf.setLength(0);
+
+        while (end != oid.length()) {
+            char c = oid.charAt(end);
+
+            if (c == '"') {
+                if (!escaped) {
+                    quoted = !quoted;
+                } else {
+                    buf.append(c);
+                }
+                escaped = false;
+            } else {
+                if (escaped || quoted) {
+                    buf.append(c);
+                    escaped = false;
+                } else if (c == '\\') {
+                    escaped = true;
+                } else if (c == ',') {
+                    break;
+                } else {
+                    buf.append(c);
+                }
+            }
+            end++;
+        }
+
+        index = end;
+        return buf.toString().trim();
+    }
+}
diff --git a/src/org/apache/ws/security/components/crypto/errors.properties b/src/org/apache/ws/security/components/crypto/errors.properties
new file mode 100644
index 0000000..4c475e5
--- /dev/null
+++ b/src/org/apache/ws/security/components/crypto/errors.properties
@@ -0,0 +1,20 @@
+## defines error code - str message mapping
+0 = General security error
+1 = An unsupported token was provided
+2 = An unsupported signature or encryption algorithm was used
+3 = An error was discovered processing the <wsse:Security> header.
+4 = An invalid security token was provided
+5 = The security token could not be authenticated or authorized
+6 = The signature or decryption was invalid
+7 = Referenced security token could not be retrieved.
+
+proxyNotFound = Proxy file ({0}) not found.
+ioError00 = Failed to load credentials.
+secError00 = Failed to load credentials.
+error00 = Failed to load credentials.
+noCerts00 = No certificates loaded
+noKey00 = No private key loaded
+noSKIHandling = Problem with SKI information: {0}
+badBase64Data = Unable to decode Base64 encoded data
+badEncoding = Problem with Encoding: {0}
+noSHA1availabe = Crypto provider does not suppor1 SHA-1 digest
diff --git a/src/org/apache/ws/security/conversation/ConversationConstants.java b/src/org/apache/ws/security/conversation/ConversationConstants.java
new file mode 100755
index 0000000..0ffdaa3
--- /dev/null
+++ b/src/org/apache/ws/security/conversation/ConversationConstants.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.conversation;
+
+/**
+ * Class ConversationConstants
+ */
+public class ConversationConstants {
+
+	private static final String NS_YEAR_PREFIX = "http://schemas.xmlsoap.org/ws/2005/02/";
+	
+    /**
+     * WS-Secure Conversation namespace
+     */
+    public final static String WSC_NS = NS_YEAR_PREFIX + "sc";
+    
+    /**
+     * TOken type of DerivedKeyToken
+     */
+    public final static String TOKEN_TYPE_DERIVED_KEY_TOKEN = WSC_NS + "/dk";
+    
+    /**
+     * Token type of SecurityContextToken
+     */
+    public static final String TOKEN_TYPE_SECURITY_CONTEXT_TOKEN = WSC_NS  + "/sct";
+    
+    /**
+     * Field WSC_PREFIX
+     */
+    public final static String WSC_PREFIX = "wsc";
+
+    /**
+     * Field SECURITY_CONTEXT_TOKEN_LN
+     */
+    public static final String SECURITY_CONTEXT_TOKEN_LN =
+            "SecurityContextToken";
+
+    /**
+     * Field IDENTIFIER_LN
+     */
+    public static final String IDENTIFIER_LN = "Identifier";
+
+    /**
+     * Field EXPIRES_LN
+     */
+    public static final String EXPIRES_LN = "Expires";
+
+    /**
+     * Field KEYS_LN
+     */
+    public static final String KEYS_LN = "Keys";
+
+    /**
+     * Field SECURITY_TOKEN_REFERENCE_LN
+     */
+    public static final String SECURITY_TOKEN_REFERENCE_LN =
+            "SecurityTokenReference";
+
+    /**
+     * Field DERIVED_KEY_TOKEN_LN
+     */
+    public static final String DERIVED_KEY_TOKEN_LN = "DerivedKeyToken";
+
+    /**
+     * Field PROPERTIES_LN
+     */
+    public static final String PROPERTIES_LN = "Properties";
+
+    /**
+     * Field LENGTH_LN
+     */
+    public static final String LENGTH_LN = "Length";
+
+    /**
+     * Field GENERATION_LN
+     */
+    public static final String GENERATION_LN = "Generation";
+
+    /**
+     * Field OFFSET_LN
+     */
+    public static final String OFFSET_LN = "Offset";
+
+    /**
+     * Field LABEL_LN
+     */
+    public static final String LABEL_LN = "Label";
+
+    /**
+     * Field NONCE_LN
+     */
+    public static final String NONCE_LN = "Nonce";
+
+    public static final int DIRECT_GENERATED = 1;
+    public static final int STS_GENERATED = 2;
+    public static final int STSREQUEST_TOKEN = 3;
+    public static final int INTEROP_SCENE1 = 4;
+
+    public static final String IDENTIFIER = "SCT_Identifier";
+
+    public static final int DK_SIGN = 1;
+    public static final int DK_ENCRYPT = 2;
+    
+    public final static String DEFAULT_LABEL = "WS-SecureConversation";
+    
+    public interface DerivationAlgorithm {
+        public final static String P_SHA_1 = "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1";
+    }
+}
diff --git a/src/org/apache/ws/security/conversation/ConversationException.java b/src/org/apache/ws/security/conversation/ConversationException.java
new file mode 100755
index 0000000..5d6b156
--- /dev/null
+++ b/src/org/apache/ws/security/conversation/ConversationException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.conversation;
+
+import org.apache.ws.security.WSSecurityException;
+
+public class ConversationException extends WSSecurityException {
+
+    /**
+     * Constructor ConversationException
+     *
+     * @param message
+     */
+    public ConversationException(String message) {
+        super(message);
+    }
+}
diff --git a/src/org/apache/ws/security/conversation/dkalgo/AlgoFactory.java b/src/org/apache/ws/security/conversation/dkalgo/AlgoFactory.java
new file mode 100755
index 0000000..9f10193
--- /dev/null
+++ b/src/org/apache/ws/security/conversation/dkalgo/AlgoFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.conversation.dkalgo;
+
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.ConversationException;
+
+/**
+ * @author Ruchith Fernando
+ */
+
+public class AlgoFactory {
+
+    /**
+     * This gives a DerivationAlgorithm instance from the default set of algorithms provided
+     *
+     * @param algorithm The algo identifier @see DeivationAlgorithm
+     * @return A derivatio algorithm
+     * @throws ConversationException If the specified algorithmis not available in
+     *                               default implementations
+     */
+    public static DerivationAlgorithm getInstance(String algorithm) throws
+            ConversationException {
+        if (algorithm.equals(ConversationConstants.DerivationAlgorithm.P_SHA_1)) {
+            return new P_SHA1();
+        } else {
+            throw new ConversationException("No such algorithm");
+        }
+    }
+
+}
diff --git a/src/org/apache/ws/security/conversation/dkalgo/DerivationAlgorithm.java b/src/org/apache/ws/security/conversation/dkalgo/DerivationAlgorithm.java
new file mode 100755
index 0000000..0153117
--- /dev/null
+++ b/src/org/apache/ws/security/conversation/dkalgo/DerivationAlgorithm.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.conversation.dkalgo;
+
+import org.apache.ws.security.conversation.ConversationException;
+
+/**
+ *
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public interface DerivationAlgorithm {
+
+    public byte[] createKey(byte[] secret, byte[] seed, int offset,
+            long length) throws ConversationException;
+}
diff --git a/src/org/apache/ws/security/conversation/dkalgo/P_SHA1.java b/src/org/apache/ws/security/conversation/dkalgo/P_SHA1.java
new file mode 100755
index 0000000..e51f4d9
--- /dev/null
+++ b/src/org/apache/ws/security/conversation/dkalgo/P_SHA1.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.conversation.dkalgo;
+
+/**
+ *
+ <pre>
+ P_SHA-1 DEFINITION
+ ==================
+ <b>P_SHA-1(secret, seed)</b> =
+ HMAC_SHA-1(secret, A(1) + seed) +
+ HMAC_SHA-1(secret, A(2) + seed) +
+ HMAC_SHA-1(secret, A(3) + seed) + ...
+ <i>Where + indicates concatenation.</i>
+ <br>
+ A() is defined as:
+ A(0) = seed
+ A(i) = HMAC_SHA-1(secret, A(i-1))
+ <br>
+ <i>Source : RFC 2246 - The TLS Protocol Version 1.0
+ Section 5. HMAC and the pseudorandom function</i>
+ </pre>
+ *
+ * @author Ruchith Fernando
+ */
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.ws.security.conversation.ConversationException;
+
+public class P_SHA1
+        implements DerivationAlgorithm {
+
+    public byte[] createKey(byte[] secret, byte[] seed, int offset,
+            long length) throws ConversationException {
+        try {
+            Mac mac = Mac.getInstance("HmacSHA1");
+
+            byte[] tempBytes = P_hash(secret, seed, mac,
+                    (offset + (int) length));
+
+            byte[] key = new byte[(int) length];
+
+            for (int i = 0; i < key.length; i++)
+                key[i] = tempBytes[i + offset];
+
+            return key;
+        } catch (Exception ex) {
+            throw new ConversationException("Key Derivation : P_SHA-1: "
+                    + ex.getMessage());
+        }
+    }
+    
+    /**
+     * From WSUsernameToken  :-)
+     *
+     * @param secret
+     * @param seed
+     * @param mac
+     * @param required
+     * @return
+     * @throws java.lang.Exception
+     */
+    private static byte[] P_hash(byte[] secret, byte[] seed, Mac mac,
+                                 int required) throws Exception {
+        byte[] out = new byte[required];
+        int offset = 0, tocpy;
+        byte[] A, tmp;
+        A = seed;
+        while (required > 0) {
+            SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
+            mac.init(key);
+            mac.update(A);
+            A = mac.doFinal();
+            mac.reset();
+            mac.init(key);
+            mac.update(A);
+            mac.update(seed);
+            tmp = mac.doFinal();
+            tocpy = min(required, tmp.length);
+            System.arraycopy(tmp, 0, out, offset, tocpy);
+            offset += tocpy;
+            required -= tocpy;
+        }
+        return out;
+    }
+
+    private static int min(int a, int b) {
+        return (a > b) ? b : a;
+    }
+
+}
diff --git a/src/org/apache/ws/security/errors.properties b/src/org/apache/ws/security/errors.properties
new file mode 100644
index 0000000..5edc9ea
--- /dev/null
+++ b/src/org/apache/ws/security/errors.properties
@@ -0,0 +1,78 @@
+## defines error code - str message mapping
+0 = General security error
+1 = An unsupported token was provided
+2 = An unsupported signature or encryption algorithm was used
+3 = An error was discovered processing the <wsse:Security> header.
+4 = An invalid security token was provided
+5 = The security token could not be authenticated or authorized
+6 = The signature verification failed
+7 = Referenced security token could not be retrieved.
+8 = Cannot encrypt/decrypt data
+9 = Signature creation failed
+
+## detailed error msgs
+noToken = Reference \"{0}\"
+noReference = <Reference> token could not be retrieved
+badReferenceURI = Reference URI is null
+unhandledToken = Security token supported but currently not handled \"{0}\"
+unsupportedBinaryTokenType = Token type \"{0}\"
+invalidConstructor = Token impl. class \"{0}\" does not provide appropriate constructor
+invalidValueType = Bad ValueType \"{0}\"
+unsupportedKeyInfo = Unsupported KeyInfo type
+invalidX509Data = Unexpected number of X509Data: {0}
+invalidCertData = Unexpected number of certificates: {0}
+noSKIHandling = Error during processing of SKI data: {0}
+invalidDataRef = Cannot handle multiple data references
+noEncryptedData = Referenced encrypted data could not be retrieved. Reference \"{0}\"
+badElement = Bad element, expected \"{0}\" while got \"{1}\"
+badTokenType00 = Bad UsernameToken Type
+badTokenType01 = Bad UsernameToken Values
+failedAuthentication = User ({0}) not authenticated
+missingUsernameToken = UsernameToken is missing
+missingSecurityHeader = Security header is missing
+missingUsername = Username is missing
+missingPassword = Password is missing
+missingPasswordType =Password attribute type is missing
+missingNonce = Nonce is missing
+missingCreated = Created time is missing
+noSecProvider = Specified security provider not available
+parseError = Cannot parse/decode the certificate data
+encodeError = Cannot encode the certificate data
+unsupportedCertType = Certificate type not supported by security provider
+invalidCert = The provided certificate is invalid
+noXMLSig = Cannot setup signature data structure
+noSKIHandling = Problem with SKI information: {0}
+keystore = Cannot access/read keystore data
+noCert = No certificate provided
+##
+noSigCryptoFile=WSSecurityEngine: No crypto protery file supplied to verify signature
+noDecCryptoFile=WSSecurityEngine: No crypto propery file supplied for decryption
+noCallback=WSSecurityEngine: No password callback supplied
+noPassword=WSSecurityEngine: Callback supplied no password for: {0}
+noKey=WSSecurityEngine: Callback supplied no key for: {0}
+noEncAlgo=WSSecurityEngine: xenc:EncryptedKey does not contain xenc:EncryptionMethod/@Algorithm
+unsupportedKeyTransp=unsupported key transport encryption algorithm: {0}
+noCipher=WSSecurityEngine: EncryptedKey does not contain xenc:CipherData/xenc:CipherValue
+noKeyinfo=WSSecurityEngine: EncryptedKey does not contain ds:KeyInfo
+noSecTokRef=WSSecurityEngine: EncryptedKey does not contain ds:KeyInfo/wsse:SecurityTokenReference
+unsupportedKeyId=Unsupported key identification
+dataRef=WSSecurityEngine: DataReference - referenced data not found
+noKeyname=WSSecurityEngine: ds:KeyName does not contain a key name
+noEncElement=WSEncryptBody/WSSignEnvelope: Element to encrypt/sign not found: {0}
+certpath=Error during certificate path validation: {0}
+invalidTimestamp=WSSecurityEngine: Invalid timestamp {0}
+noKeySupplied=WSEncryptBody: No symmetrical encryption key supplied
+#
+noSAMLdoc=Cannot convert SAML to DOM document
+invalidSAMLsecurity=SAML token security failure
+invalidData=Invalid data: {0}
+#
+decoding.divisible.four = It should be divisible by four
+decoding.general = Error while decoding
+
+unknownAction=Unknown Action {0}
+unableToLoadClass=Unable to load class {0}
+
+requiredElementNoID=Element {0} is not signed; it does not have a wsu:Id attribute
+noSignResult=No SIGN result in WSS4J result vector
+requiredElementNotSigned=Element {0} is not included in the signature
diff --git a/src/org/apache/ws/security/handler/RequestData.java b/src/org/apache/ws/security/handler/RequestData.java
new file mode 100644
index 0000000..b594709
--- /dev/null
+++ b/src/org/apache/ws/security/handler/RequestData.java
@@ -0,0 +1,238 @@
+package org.apache.ws.security.handler;
+
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.WSSecHeader;
+
+import java.util.Vector;
+import java.security.cert.X509Certificate;
+
+/**
+ * This class holds per request data.
+ *
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de)
+ */
+public class RequestData {
+    private Object msgContext = null;
+    private boolean noSerialization = false;
+    private SOAPConstants soapConstants = null;
+    private String actor = null;
+    private String username = null;
+    private String pwType = null;
+    private String[] utElements = null;
+    private Crypto sigCrypto = null;
+    private Crypto decCrypto = null;
+    private int sigKeyId = 0;
+    private String sigAlgorithm = null;
+    private Vector signatureParts = new Vector();
+    private Crypto encCrypto = null;
+    private int encKeyId = 0;
+    private String encSymmAlgo = null;
+    private String encKeyTransport = null;
+    private String encUser = null;
+    private Vector encryptParts = new Vector();
+    private X509Certificate encCert = null;
+    private int timeToLive = 300; 	// Timestamp: time in seconds between creation and expiry
+    private WSSConfig wssConfig = null;
+    private Vector signatureValues = new Vector();
+    private WSSecHeader secHeader = null;
+
+    public void clear() {
+        soapConstants = null;
+       	actor = username = pwType = sigAlgorithm = encSymmAlgo = encKeyTransport = encUser = null;
+       	sigCrypto = decCrypto = encCrypto = null;
+       	signatureParts.clear();
+       	encryptParts.clear();
+       	encCert = null;
+       	utElements = null;
+        wssConfig = null;
+        signatureValues.clear();
+    }
+
+    public Object getMsgContext() {
+        return msgContext;
+    }
+
+    public void setMsgContext(Object msgContext) {
+        this.msgContext = msgContext;
+    }
+
+    public boolean isNoSerialization() {
+        return noSerialization;
+    }
+
+    public void setNoSerialization(boolean noSerialization) {
+        this.noSerialization = noSerialization;
+    }
+
+    public SOAPConstants getSoapConstants() {
+        return soapConstants;
+    }
+
+    public void setSoapConstants(SOAPConstants soapConstants) {
+        this.soapConstants = soapConstants;
+    }
+
+    public String getActor() {
+        return actor;
+    }
+
+    public void setActor(String actor) {
+        this.actor = actor;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPwType() {
+        return pwType;
+    }
+
+    public void setPwType(String pwType) {
+        this.pwType = pwType;
+    }
+
+    public String[] getUtElements() {
+        return utElements;
+    }
+
+    public void setUtElements(String[] utElements) {
+        this.utElements = utElements;
+    }
+
+    public Crypto getSigCrypto() {
+        return sigCrypto;
+    }
+
+    public void setSigCrypto(Crypto sigCrypto) {
+        this.sigCrypto = sigCrypto;
+    }
+
+    public Crypto getDecCrypto() {
+        return decCrypto;
+    }
+
+    public void setDecCrypto(Crypto decCrypto) {
+        this.decCrypto = decCrypto;
+    }
+
+    public int getSigKeyId() {
+        return sigKeyId;
+    }
+
+    public void setSigKeyId(int sigKeyId) {
+        this.sigKeyId = sigKeyId;
+    }
+
+    public String getSigAlgorithm() {
+        return sigAlgorithm;
+    }
+
+    public void setSigAlgorithm(String sigAlgorithm) {
+        this.sigAlgorithm = sigAlgorithm;
+    }
+
+    public Vector getSignatureParts() {
+        return signatureParts;
+    }
+
+    public Crypto getEncCrypto() {
+        return encCrypto;
+    }
+
+    public void setEncCrypto(Crypto encCrypto) {
+        this.encCrypto = encCrypto;
+    }
+
+    public int getEncKeyId() {
+        return encKeyId;
+    }
+
+    public void setEncKeyId(int encKeyId) {
+        this.encKeyId = encKeyId;
+    }
+
+    public String getEncSymmAlgo() {
+        return encSymmAlgo;
+    }
+
+    public void setEncSymmAlgo(String encSymmAlgo) {
+        this.encSymmAlgo = encSymmAlgo;
+    }
+
+    public String getEncKeyTransport() {
+        return encKeyTransport;
+    }
+
+    public void setEncKeyTransport(String encKeyTransport) {
+        this.encKeyTransport = encKeyTransport;
+    }
+
+    public String getEncUser() {
+        return encUser;
+    }
+
+    public void setEncUser(String encUser) {
+        this.encUser = encUser;
+    }
+
+    public Vector getEncryptParts() {
+        return encryptParts;
+    }
+
+    public X509Certificate getEncCert() {
+        return encCert;
+    }
+
+    public void setEncCert(X509Certificate encCert) {
+        this.encCert = encCert;
+    }
+
+    public int getTimeToLive() {
+        return timeToLive;
+    }
+
+    public void setTimeToLive(int timeToLive) {
+        this.timeToLive = timeToLive;
+    }
+
+    /**
+     * @return Returns the wssConfig.
+     */
+    public WSSConfig getWssConfig() {
+        return wssConfig;
+    }
+
+    /**
+     * @param wssConfig The wssConfig to set.
+     */
+    public void setWssConfig(WSSConfig wssConfig) {
+        this.wssConfig = wssConfig;
+    }
+    /**
+     * @return Returns the vector of stored signature values.
+     */
+    public Vector getSignatureValues() {
+        return signatureValues;
+    }
+
+    /**
+     * @return Returns the secHeader.
+     */
+    public WSSecHeader getSecHeader() {
+        return secHeader;
+    }
+
+    /**
+     * @param secHeader The secHeader to set.
+     */
+    public void setSecHeader(WSSecHeader secHeader) {
+        this.secHeader = secHeader;
+    }
+}
diff --git a/src/org/apache/ws/security/handler/WSHandler.java b/src/org/apache/ws/security/handler/WSHandler.java
new file mode 100644
index 0000000..d7d5f11
--- /dev/null
+++ b/src/org/apache/ws/security/handler/WSHandler.java
@@ -0,0 +1,1087 @@
+/*
+* Copyright  2003-2005 The Apache Software Foundation.
+*
+*  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.apache.ws.security.handler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.util.Loader;
+import org.apache.ws.security.util.StringUtil;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.XmlSchemaDateFormat;
+import org.w3c.dom.Document;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
+
+/**
+ * Extracted from WSDoAllReceiver and WSDoAllSender
+ *
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de).
+ */
+public abstract class WSHandler {
+    public static String DONE = "done";
+    private static Log log = LogFactory.getLog(WSHandler.class.getName());
+    protected static final WSSecurityEngine secEngine = WSSecurityEngine.getInstance();
+    protected static Hashtable cryptos = new Hashtable(5);
+
+    private boolean doDebug = log.isDebugEnabled();
+
+    /**                                                             ut
+     * Performs all defined security actions to set-up the SOAP request.
+     * 
+     * 
+     * @param doAction a set defining the actions to do 
+     * @param doc   the request as DOM document 
+     * @param reqData a data storage to pass values around bewteen methods
+     * @param actions a vector holding the actions to do in the order defined
+     *                in the deployment file or property
+     * @throws WSSecurityException
+     */
+    protected void doSenderAction(int doAction, Document doc,
+                                  RequestData reqData, Vector actions, 
+				  boolean isRequest)
+            throws WSSecurityException {
+
+        boolean mu = decodeMustUnderstand(reqData);
+
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        
+        wssConfig
+	    .setEnableSignatureConfirmation(decodeEnableSignatureConfirmation(reqData));
+        
+        wssConfig
+	    .setPrecisionInMilliSeconds(decodeTimestampPrecision(reqData));
+        reqData.setWssConfig(wssConfig);
+
+        Object mc = reqData.getMsgContext();
+        String actor = getString(WSHandlerConstants.ACTOR, mc);
+        reqData.setActor(actor);
+
+        WSSecHeader secHeader = new WSSecHeader(actor, mu);
+        secHeader.insertSecurityHeader(doc);
+        
+        reqData.setSecHeader(secHeader);
+        reqData.setSoapConstants(WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement()));
+        /*
+         * Here we have action, username, password, and actor, mustUnderstand.
+         * Now get the action specific parameters.
+         */
+        if ((doAction & WSConstants.UT) == WSConstants.UT) {
+            decodeUTParameter(reqData);
+        }
+        /*
+         * Here we have action, username, password, and actor, mustUnderstand.
+         * Now get the action specific parameters.
+         */
+        if ((doAction & WSConstants.UT_SIGN) == WSConstants.UT_SIGN) {
+            decodeUTParameter(reqData);
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * Get and check the Signature specific parameters first because they
+         * may be used for encryption too.
+         */
+        if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+            reqData.setSigCrypto(loadSignatureCrypto(reqData));
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * If we need to handle signed SAML token then we need may of the
+         * Signature parameters. The handle procedure loads the signature crypto
+         * file on demand, thus don't do it here.
+         */
+        if ((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED) {
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * Set and check the encryption specific parameters, if necessary take
+         * over signature parameters username and crypto instance.
+         */
+        if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+            reqData.setEncCrypto(loadEncryptionCrypto(reqData));
+            decodeEncryptionParameter(reqData);
+        }
+        /*
+         * If after all the parsing no Signature parts defined, set here a
+         * default set. This is necessary because we add SignatureConfirmation
+         * and therefore the default (Body) must be set here. The default setting
+         * in WSSignEnvelope doesn't work because the vector is not empty anymore.
+         */
+        if (reqData.getSignatureParts().isEmpty()) {
+            WSEncryptionPart encP = new WSEncryptionPart(reqData.getSoapConstants()
+                    .getBodyQName().getLocalPart(), reqData.getSoapConstants()
+                    .getEnvelopeURI(), "Content");
+            reqData.getSignatureParts().add(encP);
+        }
+        /*
+         * If SignatureConfirmation is enabled and this is a reqsponse then
+         * insert SignatureCOnfrmation elements, note their wsu:id in the signature
+         * parts. They will be signed automatically during a (probably) defined
+         * SIGN action.
+         */
+        if (wssConfig.isEnableSignatureConfirmation() && !isRequest) {
+            String done;
+            if ((done = (String) getProperty(reqData.getMsgContext(),
+                    WSHandlerConstants.SIG_CONF_DONE)) == null
+                    || !DONE.equals(done)) {
+                Vector results = null;
+                if ((results = (Vector) getProperty(reqData.getMsgContext(),
+                        WSHandlerConstants.RECV_RESULTS)) != null) {
+                    wssConfig.getAction(WSConstants.SC).execute(this, WSConstants.SC, doc, reqData);
+                }
+            }
+        }
+        /*
+         * Here we have all necessary information to perform the requested
+         * action(s).
+         */
+        for (int i = 0; i < actions.size(); i++) {
+
+            int actionToDo = ((Integer) actions.get(i)).intValue();
+            if (doDebug) {
+                log.debug("Performing Action: " + actionToDo);
+            }
+
+            switch (actionToDo) {
+                case WSConstants.UT:
+                case WSConstants.ENCR:
+                case WSConstants.SIGN:
+                case WSConstants.ST_SIGNED:
+                case WSConstants.ST_UNSIGNED:
+                case WSConstants.TS:
+                case WSConstants.UT_SIGN:
+                    wssConfig.getAction(actionToDo).execute(this, actionToDo, doc, reqData);
+                    break;
+                case WSConstants.NO_SERIALIZE:
+                    reqData.setNoSerialization(true);
+                    break;
+            }
+        }
+        /*
+         * If this is a request then store all signature values. Add ours to
+         * already gathered values because of chained handlers, e.g. for
+         * other actors.
+         */
+
+        if (wssConfig.isEnableSignatureConfirmation() && isRequest) {
+            if (reqData.getSignatureValues().size() > 0) {
+                Vector sigv = null;
+                if ((sigv = (Vector) getProperty(reqData.getMsgContext(),
+                        WSHandlerConstants.SEND_SIGV)) == null) {
+                    sigv = new Vector();
+                    setProperty(reqData.getMsgContext(),
+                            WSHandlerConstants.SEND_SIGV, sigv);
+                }
+                // sigv.add(reqData.getSignatureValues());
+                sigv.addAll(reqData.getSignatureValues());
+            }
+        }
+    }
+
+
+
+	protected void doReceiverAction(int doAction, RequestData reqData)
+            throws WSSecurityException {
+
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        wssConfig
+	    .setEnableSignatureConfirmation(decodeEnableSignatureConfirmation(reqData));
+        wssConfig.setTimeStampStrict(decodeTimestampStrict(reqData));
+        reqData.setWssConfig(wssConfig);
+
+        if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+            decodeSignatureParameter2(reqData);
+        }
+
+        if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+            decodeDecryptionParameter(reqData);
+        }
+        if ((doAction & WSConstants.NO_SERIALIZE) == WSConstants.NO_SERIALIZE) {
+            reqData.setNoSerialization(true);
+        }
+    }
+
+    protected boolean checkReceiverResults(Vector wsResult, Vector actions) {
+        int resultActions = wsResult.size();
+        int size = actions.size();
+
+        // if (size != resultActions) {
+        // throw new AxisFault(
+        // "WSDoAllReceiver: security processing failed (actions number
+        // mismatch)");
+        // }
+
+        int ai = 0;
+        for (int i = 0; i < resultActions; i++) {
+            int act = ((WSSecurityEngineResult) wsResult.get(i)).getAction();
+            if (act == WSConstants.SC) {
+                continue;
+            }
+            if (ai >= size || ((Integer) actions.get(ai++)).intValue() != act) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected void checkSignatureConfirmation(RequestData reqData,
+                                              Vector wsResult) throws WSSecurityException{
+        if (doDebug) {
+            log.debug("Check Signature confirmation");
+        }
+
+        /*
+        * First get all Signature value stored during sending the request
+        */
+        Vector sigv = (Vector) getProperty(reqData.getMsgContext(),
+                WSHandlerConstants.SEND_SIGV);
+        /*
+         * Now get all results that hold a SignatureConfirmation element from
+         * the current run of receiver (we can have mor than on run: if we
+         * have several security header blocks with different actors/roles)
+         */
+        Vector sigConf = new Vector();
+        WSSecurityUtil.fetchAllActionResults(wsResult, WSConstants.SC, sigConf);
+        /*
+         * now loop over all SignatureConfirmation results and check:
+         * - if there is a signature value and no Signature value generated in request: error
+         * - if there is a signature value and no machting Signature value found: error
+         * 
+         *  If a matching value found: remove from vector of stored signature values
+         */
+        for (int i = 0; i < sigConf.size(); i++) {
+            byte[] sigVal = ((WSSecurityEngineResult)sigConf.get(i)).getSigConf().getSignatureValue();
+            if (sigVal != null) {
+                if (sigv == null || sigv.size() == 0) {
+                    throw new WSSecurityException("WSHandler: Check Signature confirmation: got a SC element, but no stored SV");
+                }
+                boolean found = false;
+                for (int ii = 0; ii < sigv.size(); ii++) {
+                    byte[] storedValue = (byte[])sigv.get(i);
+                    if (Arrays.equals(sigVal, storedValue)) {
+                        found = true;
+                        sigv.remove(ii);
+                        break;
+                    }
+                }
+                if (!found) {
+                    throw new WSSecurityException("WSHandler: Check Signature confirmation: got SC element, but no matching SV");
+                }
+            }
+        }
+
+        /*
+        * This indicates this is the last handler: the vector holding the
+        * stored Signature values must be empty, otherwise we have an error
+        */
+        if (!reqData.isNoSerialization()) {
+            log.debug("Check Signature confirmation - last handler");
+            if (sigv != null && !sigv.isEmpty()) {
+                throw new WSSecurityException("WSHandler: Check Signature confirmation: stored SV vector not empty");
+            }
+        }
+    }
+    /**
+     * Hook to allow subclasses to load their Signature Crypto however they see
+     * fit.
+     */
+    public Crypto loadSignatureCrypto(RequestData reqData) 
+	throws WSSecurityException {
+        Crypto crypto = null;
+        /*
+        * Get crypto property file for signature. If none specified throw
+        * fault, otherwise get a crypto instance.
+        */
+        String sigPropFile = getString(WSHandlerConstants.SIG_PROP_FILE,
+				       reqData.getMsgContext());
+        if (sigPropFile != null) {
+            if ((crypto = (Crypto) cryptos.get(sigPropFile)) == null) {
+                crypto = CryptoFactory.getInstance(sigPropFile, this.getClassLoader());
+                cryptos.put(sigPropFile, crypto);
+            }
+        } else {
+            throw new WSSecurityException(
+                "WSHandler: Signature: no crypto property file");
+        }
+        return crypto;
+    }
+
+    /**
+     * Hook to allow subclasses to load their Encryption Crypto however they
+     * see fit.
+     */
+    protected Crypto loadEncryptionCrypto(RequestData reqData) 
+	throws WSSecurityException {
+        Crypto crypto = null;
+        /*
+        * Get encryption crypto property file. If non specified take crypto
+        * instance from signature, if that fails: throw fault
+        */
+        String encPropFile = getString(WSHandlerConstants.ENC_PROP_FILE,
+				       reqData.getMsgContext());
+        if (encPropFile != null) {
+            if ((crypto = (Crypto) cryptos.get(encPropFile)) == null) {
+                crypto = CryptoFactory.getInstance(encPropFile, this.getClassLoader());
+                cryptos.put(encPropFile, crypto);
+            }
+        } else if ((crypto = reqData.getSigCrypto()) == null) {
+            throw new WSSecurityException(
+                "WSHandler: Encryption: no crypto property file");
+        }
+        return crypto;
+    }
+
+    protected void decodeUTParameter(RequestData reqData) 
+	throws WSSecurityException {
+	Object mc = reqData.getMsgContext();
+
+        String type = getString(WSHandlerConstants.PASSWORD_TYPE, mc);
+	reqData.setPwType(type);
+        if (type != null) {
+            reqData.setPwType(type.equals(WSConstants.PW_TEXT)
+			      ? WSConstants.PASSWORD_TEXT
+			      : WSConstants.PASSWORD_DIGEST);
+        }
+
+        String add = getString(WSHandlerConstants.ADD_UT_ELEMENTS, mc);
+        if (add != null) {
+            reqData.setUtElements(StringUtil.split(add, ' '));
+        }
+    }
+
+    protected void decodeSignatureParameter(RequestData reqData) 
+	throws WSSecurityException {
+	Object mc = reqData.getMsgContext();
+        String keyId = getString(WSHandlerConstants.SIG_KEY_ID, mc);
+        if (keyId != null) {
+            Integer id = (Integer) WSHandlerConstants.keyIdentifier.get(keyId);
+            if (id == null) {
+                throw new WSSecurityException(
+                     "WSHandler: Signature: unknown key identification");
+            }
+            int tmp = id.intValue();
+            if (!(tmp == WSConstants.ISSUER_SERIAL
+		  || tmp == WSConstants.BST_DIRECT_REFERENCE
+		  || tmp == WSConstants.X509_KEY_IDENTIFIER
+		  || tmp == WSConstants.SKI_KEY_IDENTIFIER
+		  || tmp == WSConstants.THUMBPRINT_IDENTIFIER)) {
+                throw new WSSecurityException(
+                        "WSHandler: Signature: illegal key identification");
+            }
+            reqData.setSigKeyId(tmp);
+        }
+        String algo = getString(WSHandlerConstants.SIG_ALGO, mc);
+        reqData.setSigAlgorithm(algo);
+
+        String parts = getString(WSHandlerConstants.SIGNATURE_PARTS, mc);
+        if (parts != null) {
+            splitEncParts(parts, reqData.getSignatureParts(), reqData);
+        }
+    }
+
+    protected void decodeEncryptionParameter(RequestData reqData) 
+	throws WSSecurityException {
+	Object mc = reqData.getMsgContext();
+        String encUser = getString(WSHandlerConstants.ENCRYPTION_USER, mc);
+	
+        if (encUser != null) {
+	    reqData.setEncUser(encUser);
+        } else {
+            reqData.setEncUser(reqData.getUsername());
+	}
+        if (reqData.getEncUser() == null) {
+	    throw new WSSecurityException("WSHandler: Encryption: no username");
+        }
+        /*
+        * String msgType = msgContext.getCurrentMessage().getMessageType(); if
+        * (msgType != null && msgType.equals(Message.RESPONSE)) {
+        * handleSpecialUser(encUser); }
+        */
+        handleSpecialUser(reqData);
+	
+        /*
+        * If the following parameters are no used (they return null) then the
+        * default values of WSS4J are used.
+        */
+        String encKeyId = getString(WSHandlerConstants.ENC_KEY_ID, mc);
+        if (encKeyId != null) {
+            Integer id = (Integer) WSHandlerConstants
+		.keyIdentifier.get(encKeyId);
+            if (id == null) {
+                throw new WSSecurityException(
+		      "WSHandler: Encryption: unknown key identification");
+            }
+            int tmp = id.intValue();
+	    reqData.setEncKeyId(tmp);
+	    if (!(tmp == WSConstants.ISSUER_SERIAL
+		  || tmp == WSConstants.X509_KEY_IDENTIFIER
+		  || tmp == WSConstants.SKI_KEY_IDENTIFIER
+		  || tmp == WSConstants.BST_DIRECT_REFERENCE
+		  || tmp == WSConstants.EMBEDDED_KEYNAME
+		  || tmp == WSConstants.THUMBPRINT_IDENTIFIER)) {
+                throw new WSSecurityException(
+                          "WSHandler: Encryption: illegal key identification");
+            }
+	}
+        String encSymAlgo = getString(WSHandlerConstants.ENC_SYM_ALGO, mc);
+        reqData.setEncSymmAlgo(encSymAlgo);
+
+        String encKeyTransport 
+	    = getString(WSHandlerConstants.ENC_KEY_TRANSPORT, mc);
+        reqData.setEncKeyTransport(encKeyTransport);
+
+        String encParts = getString(WSHandlerConstants.ENCRYPTION_PARTS, mc);
+        if (encParts != null) {
+            splitEncParts(encParts, reqData.getEncryptParts(), reqData);
+        }
+    }
+
+    protected boolean decodeMustUnderstand(RequestData reqData) 
+	throws WSSecurityException {
+        String mu = getString(WSHandlerConstants.MUST_UNDERSTAND,
+			      reqData.getMsgContext());
+
+        if (mu == null) {return true;}
+
+	if ("0".equals(mu) || "false".equals(mu)) {return false;} 
+	if ("1".equals(mu) || "true".equals(mu)) {return true;}
+
+	throw new WSSecurityException(
+              "WSHandler: illegal mustUnderstand parameter");
+    }
+
+    public int decodeTimeToLive(RequestData reqData) {
+        String ttl = getString(WSHandlerConstants.TTL_TIMESTAMP,
+			       reqData.getMsgContext());
+        int ttl_i = 0;
+        if (ttl != null) {
+            try {
+                ttl_i = Integer.parseInt(ttl);
+            } catch (NumberFormatException e) {
+                ttl_i = reqData.getTimeToLive();
+            }
+        }
+        if (ttl_i <= 0) {
+            ttl_i = reqData.getTimeToLive();
+        }
+        return ttl_i;
+    }
+    
+    protected boolean decodeEnableSignatureConfirmation(RequestData reqData) throws WSSecurityException {
+
+    	String value = getString(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION,
+				 reqData.getMsgContext());
+
+    	if (value == null) {return true;}
+
+       	if ("0".equals(value) || "false".equals(value)) {return false;} 
+       	if ("1".equals(value) || "true".equals(value)) {return true;}
+
+    	throw new WSSecurityException(
+    		   "WSHandler: illegal enableSignatureConfirmation parameter");
+	}
+
+    protected boolean decodeTimestampPrecision(RequestData reqData) 
+	throws WSSecurityException {
+        boolean precisionInMilliSeconds = true;
+        String value = getString(WSHandlerConstants.TIMESTAMP_PRECISION,
+				 reqData.getMsgContext());
+
+        if (value == null) {return true;}
+
+	if ("0".equals(value) || "false".equals(value)) {return false;} 
+	if ("1".equals(value) || "true".equals(value)) {return true;}
+
+	throw new WSSecurityException(
+		   "WSHandler: illegal precisionInMilliSeconds parameter");
+    }
+
+    protected boolean decodeTimestampStrict(RequestData reqData) 
+	throws WSSecurityException {
+        boolean precisionInMilliSeconds = true;
+        String value = getString(WSHandlerConstants.TIMESTAMP_STRICT,
+				 reqData.getMsgContext());
+
+        if (value == null) {return true;}
+
+	if ("0".equals(value) || "false".equals(value)) {return false;} 
+	if ("1".equals(value) || "true".equals(value)) {return true;}
+
+	throw new WSSecurityException(
+		   "WSHandler: illegal timestampStrict parameter");
+    }
+
+
+    /**
+     * Get a password to construct a UsernameToken or sign a message.
+     * <p/>
+     * Try all possible sources to get a password.
+     */
+    public WSPasswordCallback getPassword(String username,
+                                          int doAction,
+                                          String clsProp,
+                                          String refProp,
+                                          RequestData reqData)
+            throws WSSecurityException {
+        WSPasswordCallback pwCb = null;
+        String password = null;
+        CallbackHandler cbHandler = null;
+	String err = "provided null or empty password";
+	Object mc = reqData.getMsgContext();
+        String callback = getString(clsProp, mc);
+        if (callback != null) { // we have a password callback class
+            pwCb = readPwViaCallbackClass(callback, username, doAction);
+            if ((pwCb.getPassword() == null) && (pwCb.getKey() == null)) {
+            throw new WSSecurityException("WSHandler: password callback class "
+					  +err);
+            }
+        } else if ((cbHandler = (CallbackHandler) getProperty(mc, refProp))
+		   != null) {
+            pwCb = performCallback(cbHandler, username, doAction);
+            if ((pwCb.getPassword() == null) && (pwCb.getKey() == null)) {
+                throw new WSSecurityException("WSHandler: password callback " 
+					      +err);
+            }
+        } else if ((password = getPassword(mc)) == null) {
+            throw new WSSecurityException("WSHandler: application "+err);
+        } else {
+            setPassword(mc, null);
+            pwCb = new WSPasswordCallback("", WSPasswordCallback.UNKNOWN);
+            pwCb.setPassword(password);
+        }
+        return pwCb;
+    }
+
+    private WSPasswordCallback readPwViaCallbackClass(String callback,
+                                                      String username,
+                                                      int doAction)
+            throws WSSecurityException {
+
+        Class cbClass = null;
+        CallbackHandler cbHandler = null;
+        try {
+            cbClass = Loader.loadClass(getClassLoader(), callback);
+        } catch (ClassNotFoundException e) {
+            throw new WSSecurityException("WSHandler: cannot load password callback class: "
+                    + callback,
+                    e);
+        }
+        try {
+            cbHandler = (CallbackHandler) cbClass.newInstance();
+        } catch (Exception e) {
+            throw new WSSecurityException("WSHandler: cannot create instance of password callback: "
+                    + callback,
+                    e);
+        }
+        return (performCallback(cbHandler, username, doAction));
+    }
+
+    /**
+     * Perform a callback to get a password.
+     * <p/>
+     * The called back function gets an indication why to provide a password:
+     * to produce a UsernameToken, Signature, or a password (key) for a given
+     * name.
+     */
+    private WSPasswordCallback performCallback(CallbackHandler cbHandler,
+                                               String username,
+                                               int doAction)
+            throws WSSecurityException {
+
+        WSPasswordCallback pwCb = null;
+        int reason = 0;
+
+        switch (doAction) {
+        case WSConstants.UT:
+        case WSConstants.UT_SIGN:
+                reason = WSPasswordCallback.USERNAME_TOKEN;
+                break;
+            case WSConstants.SIGN:
+                reason = WSPasswordCallback.SIGNATURE;
+                break;
+            case WSConstants.ENCR:
+                reason = WSPasswordCallback.KEY_NAME;
+                break;
+        }
+        pwCb = new WSPasswordCallback(username, reason);
+        Callback[] callbacks = new Callback[1];
+        callbacks[0] = pwCb;
+        /*
+        * Call back the application to get the password
+        */
+        try {
+            cbHandler.handle(callbacks);
+        } catch (Exception e) {
+            throw new WSSecurityException("WSHandler: password callback failed", e);
+        }
+        return pwCb;
+    }
+
+    private void splitEncParts(String tmpS, Vector parts, RequestData reqData)
+            throws WSSecurityException {
+        WSEncryptionPart encPart = null;
+        String[] rawParts = StringUtil.split(tmpS, ';');
+
+        for (int i = 0; i < rawParts.length; i++) {
+            String[] partDef = StringUtil.split(rawParts[i], '}');
+
+            if (partDef.length == 1) {
+                if (doDebug) {
+                    log.debug("single partDef: '" + partDef[0] + "'");
+                }
+                encPart =
+                        new WSEncryptionPart(partDef[0].trim(),
+                                reqData.getSoapConstants().getEnvelopeURI(),
+                                "Content");
+            } else if (partDef.length == 3) {
+                String mode = partDef[0].trim();
+                if (mode.length() <= 1) {
+                    mode = "Content";
+                } else {
+                    mode = mode.substring(1);
+                }
+                String nmSpace = partDef[1].trim();
+                if (nmSpace.length() <= 1) {
+                    nmSpace = reqData.getSoapConstants().getEnvelopeURI();
+                } else {
+                    nmSpace = nmSpace.substring(1);
+                    if (nmSpace.equals(WSConstants.NULL_NS)) {
+                        nmSpace = null;
+                    }
+                }
+                String element = partDef[2].trim();
+                if (doDebug) {
+                    log.debug("partDefs: '"
+                            + mode
+                            + "' ,'"
+                            + nmSpace
+                            + "' ,'"
+                            + element
+                            + "'");
+                }
+                encPart = new WSEncryptionPart(element, nmSpace, mode);
+            } else {
+                throw new WSSecurityException("WSHandler: wrong part definition: " + tmpS);
+            }
+            parts.add(encPart);
+        }
+    }
+
+    private void handleSpecialUser(RequestData reqData) {
+        if (!WSHandlerConstants.USE_REQ_SIG_CERT.equals(reqData.getEncUser())) {
+            return;
+        }
+        Vector results = null;
+        if ((results =
+                (Vector) getProperty(reqData.getMsgContext(), WSHandlerConstants.RECV_RESULTS))
+                == null) {
+            return;
+        }
+        /*
+        * Scan the results for a matching actor. Use results only if the
+        * receiving Actor and the sending Actor match.
+        */
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                    (WSHandlerResult) results.get(i);
+            String hActor = rResult.getActor();
+            if (!WSSecurityUtil.isActorEqual(reqData.getActor(), hActor)) {
+                continue;
+            }
+            Vector wsSecEngineResults = rResult.getResults();
+            /*
+            * Scan the results for the first Signature action. Use the
+            * certificate of this Signature to set the certificate for the
+            * encryption action :-).
+            */
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                        (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                if (wser.getAction() == WSConstants.SIGN) {
+                    reqData.setEncCert(wser.getCertificate());
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Hook to allow subclasses to load their Decryption Crypto however they 
+     * see fit.
+     */
+    protected Crypto loadDecryptionCrypto(RequestData reqData) 
+	throws WSSecurityException {
+
+        Crypto crypto = null;
+        String decPropFile = getString(WSHandlerConstants.DEC_PROP_FILE,
+				     reqData.getMsgContext());
+        if (decPropFile != null) {
+            if ((crypto = (Crypto) cryptos.get(decPropFile)) == null) {
+                crypto = CryptoFactory.getInstance(decPropFile, this.getClassLoader());
+                cryptos.put(decPropFile, crypto);
+            }
+        } else if ((crypto = reqData.getSigCrypto()) == null) {
+            throw new WSSecurityException(
+                            "WSHandler: Encryption: no crypto property file");
+        }
+        return crypto;
+    }
+
+    protected void decodeSignatureParameter2(RequestData reqData) 
+	throws WSSecurityException {
+        reqData.setSigCrypto(loadSignatureCrypto(reqData));
+        /* There are currently no other signature parameters that need 
+	 * to be handled here, but we call the load crypto hook rather 
+	 * than just changing the visibility
+	 * of this method to maintain parity with WSDoAllSender.
+	 */
+    }
+
+    /*
+     * Set and check the decryption specific parameters, if necessary
+     * take over signatur crypto instance.
+     */
+
+    protected void decodeDecryptionParameter(RequestData reqData) 
+	throws WSSecurityException {
+        reqData.setDecCrypto(loadDecryptionCrypto(reqData));
+        /* There are currently no other decryption parameters that need 
+	 * to be handled here, but we call the load crypto hook rather 
+	 * than just changing the visibility
+	 * of this method to maintain parity with WSDoAllSender.
+	 */
+    }
+
+    /**
+     * Get the password callback class and get an instance
+     * <p/>
+     */
+    protected CallbackHandler getPasswordCB(RequestData reqData) 
+	throws WSSecurityException {
+
+	Object mc = reqData.getMsgContext();
+        CallbackHandler cbHandler = null;
+        String callback = getString(WSHandlerConstants.PW_CALLBACK_CLASS, mc);
+        if (callback != null) {
+            Class cbClass = null;
+            try {
+                cbClass = Loader.loadClass(getClassLoader(), callback);
+            } catch (ClassNotFoundException e) {
+                throw new WSSecurityException(
+                       "WSHandler: cannot load password callback class: "
+		       + callback, e);
+            }
+            try {
+                cbHandler = (CallbackHandler) cbClass.newInstance();
+            } catch (java.lang.Exception e) {
+                throw new WSSecurityException(
+                     "WSHandler: cannot create instance of password callback: "
+		     + callback, e);
+            }
+        } else {
+            cbHandler = (CallbackHandler) getProperty(mc, 
+				           WSHandlerConstants.PW_CALLBACK_REF);
+            if (cbHandler == null) {
+                throw new WSSecurityException(
+                           "WSHandler: no reference in callback property");
+            }
+        }
+        return cbHandler;
+    }
+
+    /**
+     * Evaluate whether a given certificate should be trusted.
+     * Hook to allow subclasses to implement custom validation methods however they see fit.
+     * <p/>
+     * Policy used in this implementation:
+     * 1. Search the keystore for the transmitted certificate
+     * 2. Search the keystore for a connection to the transmitted certificate
+     * (that is, search for certificate(s) of the issuer of the transmitted certificate
+     * 3. Verify the trust path for those certificates found because the search for the issuer might be fooled by a phony DN (String!)
+     *
+     * @param cert the certificate that should be validated against the keystore
+     * @return true if the certificate is trusted, false if not (AxisFault is thrown for exceptions during CertPathValidation)
+     * @throws WSSecurityException
+     */
+    protected boolean verifyTrust(X509Certificate cert, RequestData reqData) throws WSSecurityException {
+
+        // If no certificate was transmitted, do not trust the signature
+        if (cert == null) {
+            return false;
+        }
+
+        String[] aliases = null;
+        String alias = null;
+        X509Certificate[] certs;
+
+        String subjectString = cert.getSubjectDN().getName();
+        String issuerString = cert.getIssuerDN().getName();
+        BigInteger issuerSerial = cert.getSerialNumber();
+
+        if (doDebug) {
+            log.debug("WSHandler: Transmitted certificate has subject " + subjectString);
+            log.debug("WSHandler: Transmitted certificate has issuer " + issuerString + " (serial " + issuerSerial + ")");
+        }
+
+        // FIRST step
+        // Search the keystore for the transmitted certificate
+
+        // Search the keystore for the alias of the transmitted certificate
+        try {
+            alias = reqData.getSigCrypto().getAliasForX509Cert(issuerString, issuerSerial);
+        } catch (WSSecurityException ex) {
+            throw new WSSecurityException("WSHandler: Could not get alias for certificate with " + subjectString, ex);
+        }
+
+        if (alias != null) {
+            // Retrieve the certificate for the alias from the keystore
+            try {
+                certs = reqData.getSigCrypto().getCertificates(alias);
+            } catch (WSSecurityException ex) {
+                throw new WSSecurityException("WSHandler: Could not get certificates for alias " + alias, ex);
+            }
+
+            // If certificates have been found, the certificates must be compared
+            // to ensure againgst phony DNs (compare encoded form including signature)
+            if (certs != null && certs.length > 0 && cert.equals(certs[0])) {
+                if (doDebug) {
+                    log.debug("Direct trust for certificate with " + subjectString);
+                }
+                return true;
+            }
+        } else {
+            if (doDebug) {
+                log.debug("No alias found for subject from issuer with " + issuerString + " (serial " + issuerSerial + ")");
+            }
+        }
+
+        // SECOND step
+        // Search for the issuer of the transmitted certificate in the keystore
+
+        // Search the keystore for the alias of the transmitted certificates issuer
+        try {
+            aliases = reqData.getSigCrypto().getAliasesForDN(issuerString);
+        } catch (WSSecurityException ex) {
+            throw new WSSecurityException("WSHandler: Could not get alias for certificate with " + issuerString, ex);
+        }
+
+        // If the alias has not been found, the issuer is not in the keystore
+        // As a direct result, do not trust the transmitted certificate
+        if (aliases == null || aliases.length < 1) {
+            if (doDebug) {
+                log.debug("No aliases found in keystore for issuer " + issuerString + " of certificate for " + subjectString);
+            }
+            return false;
+        }
+
+        // THIRD step
+        // Check the certificate trust path for every alias of the issuer found in the keystore
+        for (int i = 0; i < aliases.length; i++) {
+            alias = aliases[i];
+
+            if (doDebug) {
+                log.debug("Preparing to validate certificate path with alias " + alias + " for issuer " + issuerString);
+            }
+
+            // Retrieve the certificate(s) for the alias from the keystore
+            try {
+                certs = reqData.getSigCrypto().getCertificates(alias);
+            } catch (WSSecurityException ex) {
+                throw new WSSecurityException("WSHandler: Could not get certificates for alias " + alias, ex);
+            }
+
+            // If no certificates have been found, there has to be an error:
+            // The keystore can find an alias but no certificate(s)
+            if (certs == null | certs.length < 1) {
+                throw new WSSecurityException("WSHandler: Could not get certificates for alias " + alias);
+            }
+
+            // Form a certificate chain from the transmitted certificate
+            // and the certificate(s) of the issuer from the keystore
+            // First, create new array
+            X509Certificate[] x509certs = new X509Certificate[certs.length + 1];
+            // Then add the first certificate ...
+            x509certs[0] = cert;
+            // ... and the other certificates
+            for (int j = 0; j < certs.length; j++) {
+                cert = certs[i];
+                x509certs[certs.length + j] = cert;
+            }
+            certs = x509certs;
+
+            // Use the validation method from the crypto to check whether the subjects certificate was really signed by the issuer stated in the certificate
+            try {
+                if (reqData.getSigCrypto().validateCertPath(certs)) {
+                    if (doDebug) {
+                        log.debug("WSHandler: Certificate path has been verified for certificate with subject " + subjectString);
+                    }
+                    return true;
+                }
+            } catch (WSSecurityException ex) {
+                throw new WSSecurityException("WSHandler: Certificate path verification failed for certificate with subject " + subjectString, ex);
+            }
+        }
+
+        log.debug("WSHandler: Certificate path could not be verified for certificate with subject " + subjectString);
+        return false;
+    }
+
+    /**
+	 * Evaluate whether a timestamp is considered valid on receiverside. Hook to
+	 * allow subclasses to implement custom validation methods however they see
+	 * fit.
+	 * 
+	 * Policy used in this implementation:
+	 * 
+	 * 1. The receiver can set its own time to live (besides from that set on
+	 * sender side)
+	 * 
+	 * 2. If the message was created before (now-ttl) the message is rejected
+	 * 
+	 * @param timestamp
+	 *            the timestamp that is validated
+	 * @param timeToLive
+	 *            the limit on receiverside, the timestamp is validated against
+	 * @return true if the timestamp is before (now-timeToLive), false otherwise
+	 * @throws WSSecurityException
+	 */
+    protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) throws WSSecurityException {
+
+        // Calculate the time that is allowed for the message to travel
+        Calendar validCreation = Calendar.getInstance();
+        long currentTime = validCreation.getTime().getTime();
+        currentTime -= timeToLive * 1000;
+        validCreation.setTime(new Date(currentTime));
+
+        if (doDebug) {
+			log.debug("Preparing to verify the timestamp");
+			DateFormat zulu = new XmlSchemaDateFormat();
+			log.debug("Validation of Timestamp: Current time is "
+					+ zulu.format(Calendar.getInstance().getTime()));
+			log.debug("Validation of Timestamp: Valid creation is "
+					+ zulu.format(validCreation.getTime()));
+			if (timestamp.getCreated() != null) {
+				log.debug("Validation of Timestamp: Timestamp created is "
+						+ zulu.format(timestamp.getCreated().getTime()));
+			}
+		}
+        // Validate the time it took the message to travel
+        // if (timestamp.getCreated().before(validCreation) ||
+        // !timestamp.getCreated().equals(validCreation)) {
+        Calendar cre = timestamp.getCreated();
+        if (cre != null && !cre.after(validCreation)) {
+            if (doDebug) {
+                log.debug("Validation of Timestamp: The message was created too long ago");
+            }
+            return false;
+        }
+
+        if (doDebug) {
+        	log.debug("Validation of Timestamp: Everything is ok");
+        }
+        return true;
+    }
+    
+    /**
+     * Looks up key first via {@link #getOption(String)} and if not found
+     * there, via {@link #getProperty(Object, String)}
+     *
+     * @param key the key to search for. May not be null.
+     * @param mc the message context to search. 
+     * @return the value found.
+     * @throws IllegalArgumentException if <code>key</code> is null.
+     */
+    public String getString(String key, Object mc) { 
+	if (key == null) {
+	    throw new IllegalArgumentException("Key cannot be null");
+	}
+        String s = getStringOption(key);
+	if (s != null) {
+	    return s;
+	}
+	if (mc == null) {
+	    throw new 
+		IllegalArgumentException("Message context cannot be null");
+	}
+	return (String) getProperty(mc, key);
+    }
+
+
+    /**
+     * Returns the option on <code>name</code>.
+     *
+     * @param key the non-null key of the option.
+     * @return the option on <code>key</code> if <code>key</code>
+     *  exists and is of type java.lang.String; otherwise null.
+     */
+    public String getStringOption(String key) {
+        Object o = getOption(key);
+	if (o instanceof String){
+	    return (String) o;
+	} else {
+	    return null;
+	}
+    }
+
+	/**
+	 * Returns the classloader to be used for loading the callback class
+	 * 
+	 * @return class loader
+	 */
+	public ClassLoader getClassLoader() {
+		try {
+			return Loader.getTCL();
+		} catch (Throwable t) {
+			return null;
+		}
+	}
+	
+    public abstract Object getOption(String key);
+    public abstract Object getProperty(Object msgContext, String key);
+
+    public abstract void setProperty(Object msgContext, String key, 
+				     Object value);
+
+
+    public abstract String getPassword(Object msgContext);
+
+    public abstract void setPassword(Object msgContext, String password);
+}
diff --git a/src/org/apache/ws/security/handler/WSHandlerConstants.java b/src/org/apache/ws/security/handler/WSHandlerConstants.java
new file mode 100644
index 0000000..e328ea1
--- /dev/null
+++ b/src/org/apache/ws/security/handler/WSHandlerConstants.java
@@ -0,0 +1,715 @@
+/*
+
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.handler;
+
+import org.apache.ws.security.WSConstants;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+ * This class defines the names, actions, and other string for the deployment
+ * data of the WSS handler. Both the Axis handler as well as the JAX-RPC handler
+ * use this class.
+ *  
+ * @author Werner Dittmann (werner@apache.org)
+ */
+
+public class WSHandlerConstants {
+    /**
+     * The action parameter. The
+     * handlers use the value of this parameter to determine how
+     * to process the SOAP Envelope. For example in a Axis WSDD file:
+     * <pre>
+     * &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender">
+     * &lt;parameter name="action" value="UsernameToken"/>
+     * ...
+     * </pre>
+     * orders the handler to attach a <code>UsernameToken</code> to the SOAP
+     * enevelope. It is a blank separated list of actions to perform.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting)
+     */
+    public static final String ACTION = "action";
+    public static final String SEND = "send";
+    public static final String RECEIVE = "receive";
+
+    /**
+     * Perform nothing.
+     */
+    public static final String NO_SECURITY = "NoSecurity";
+
+    /**
+     * Perform a UsernameToken identification only.
+     */
+    public static final String USERNAME_TOKEN = "UsernameToken";
+
+    /**
+     * Perform a SAML Token identification.
+     */
+    public static final String SAML_TOKEN_UNSIGNED = "SAMLTokenUnsigned";
+    public static final String SAML_TOKEN_SIGNED = "SAMLTokenSigned";
+
+    /**
+     * Perform Signature.
+     * The signature specific parameters define how to sign, which keys
+     * to use, and so on
+     */
+    public static final String SIGNATURE = "Signature";
+
+    /**
+     * Perform Encryption.
+     * The encryption specific parameters define how to encrypt, which keys
+     * to use, and so on.
+     */
+    public static final String ENCRYPT = "Encrypt";
+
+    /**
+     * Add a timestamp to the security header.
+     */
+    public static final String TIMESTAMP = "Timestamp";
+
+    /**
+     * Supress the serialization of the SOAP message.
+     * <p/>
+     * Usually the handler serializes the processed SOAP message into a string
+     * and sets it into the Axis message context as new current message. To
+     * supress this action, define this action. In this case the handler
+     * stores the processed SOAP message as <code>Document</code> in the
+     * Axis message context with the property name <code>SND_SECURITY</code>.
+     * <p/>
+     * A chained handler can retrieve the SOAP message and process it. The
+     * last handler in the chain must set the processed SOAP message as
+     * current message in Axis message context.
+     */
+    public static final String NO_SERIALIZATION = "NoSerialization";
+
+    /**
+     * Use this to use a specific signature mechanism for .Net.
+     * This signature mechanism uses data from the username token and
+     * a well defined constant string and constructs a signature
+     * key. 
+     */
+    public static final String SIGN_WITH_UT_KEY = "UsernameTokenSignature";
+
+    /**
+     * This is an interal property name to support handler chaining.
+     * The Axis WSS4J handlers use this message context property to
+     * hand over the SOAP partially processed envelope document to
+     * the next WSS4J handler in the chain.
+     */
+    public static final String SND_SECURITY = "SND_SECURITY";
+
+    /**
+     * The actor name of the <code>wsse:Security</code> header.
+     * <p/>
+     * If this parameter is omitted, the actor name is not set. Please
+     * refer to {@link org.apache.axis.Constants#ATTR_ACTOR} and {@link org.apache.axis.Constants#ATTR_ROLE}
+     * about the parameter names. They are set to <code>"actor"</code>
+     * and <code>"role"</code> respectively.
+     * <p/>
+     * The value of the actor or role has to match the receiver's setting
+     * or may contain standard values.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ACTOR, "ActorName");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     *
+     * @see org.apache.axis.Constants#URI_SOAP11_NEXT_ACTOR
+     * @see org.apache.axis.Constants#URI_SOAP12_NEXT_ROLE
+     */
+    public static final String ACTOR = "actor";
+
+    /**
+     * The role name of the <code>wsse:Security</code> header.
+     * This is used for SOAP 1.2. Refer also to {@link #ACTOR}.
+     */
+    public static final String ROLE = "role";
+
+    /**
+     * Sets the <code>mustUnderstand</code> flag.
+     * <p/>
+     * If the parameter has the value <code>1</code>
+     * or <code>true</code> the <code>mustUnderstand</code> is set.
+     * The values <code>0</code> or <code>false</code> supress the
+     * flag.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.MUST_UNDERSTAND, "false");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * The default setting is <code>true</code>
+     * <p/>
+     * Please refer to {@link org.apache.axis.Constants#ATTR_MUST_UNDERSTAND}
+     * about the parameter name (<code>"mustUnderstand"</code>).
+     */
+    public static final String MUST_UNDERSTAND = "mustUnderstand";
+
+    /**
+     * The user's name. It is used differently by the WS Security functions.
+     * <ul>
+     * <li>The <i>UsernameToken</i> function sets this name in the
+     * <code>UsernameToken</code>.
+     * </li>
+     * <li>The <i>Signing</i> function uses this name as the alias name
+     * in the keystore to get user's certificate and private key to
+     * perform signing.
+     * </li>
+     * <li>The <i>encryption</i>
+     * functions uses this parameter as fallback if {@link #ENCRYPTION_USER}
+     * is not used.
+     * </li>
+     * </ul>
+     * It is also possible to set the user's name and the according password
+     * via the call function, for example:
+     * <pre>
+     * ...
+     * call.setUsername("name");
+     * call.setPassword("WSS4Java");
+     * ...
+     * </pre>
+     * The user parameter in the deployment descritor (WSDD) file overwrites
+     * the application's setting.
+     * </p>
+     * For an additional way to set the password refer to
+     * {@link #PW_CALLBACK_CLASS} and {@link #PW_CALLBACK_REF}.
+     * <p/>
+     * If the security functions uses the username from the message context, it
+     * clears the username from the message context
+     * after they copied it. This prevents sending of the username in the
+     * HTTP header.
+     * <p/>
+     * In this case the HTTP authentication mechansisms do <b>not</b> work
+     * anymore. User authentication shall be done via the username token or
+     * the certificate verification of the signature certificate.
+     */
+    public static final String USER = "user";
+
+    /**
+     * The Axis WSS4J handlers provide several ways to get the password required
+     * to construct a username token or to sign a message.
+     * In addition the callback class may check if a username/password
+     * combination is valid. Refer to the documentation of 
+     * {@link org.apache.ws.security.WSPasswordCallback} for more information
+     * about this feature.
+     * <ul>
+     * <li> A class that implements a callback interface (see below). The
+     * handler loads this class and calls the callback method. This
+     * class must have a public default constructor with not parameters.
+     * </li>
+     * <li> The application (or a preceeding handler) sets a reference to an
+     * object that implements the callback interface
+     * </li>
+     * <li> The application sets the password directly using the
+     * <code>setPassword</code> function of the <code>Call</code>.
+     * </ul>
+     * The callback class or callback object shall implement specific password
+     * getter methods, for example reading a database or directory.
+     * <p/>
+     * The handler first checks if it can get a the password via a callback
+     * class. If that fails it checks if it can get the password from the
+     * object reference, if that also fails the handler tries the password
+     * property.
+     * <p/>
+     * The following parameter defines a class that implements a callback
+     * handler interface. The handler loads the class and calls the callback
+     * handler method to get the password. The callback
+     * class needs to implement the
+     * {@link javax.security.auth.callback.CallbackHandler} interface.
+     * <p/>
+     * The callback function
+     * {@link javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])}
+     * gets an array of {@link org.apache.ws.security.WSPasswordCallback}
+     * objects. Only the first entry of the array is used. This object
+     * contains the username/keyname as identifier. The callback handler must
+     * set the password or key associated with this identifier before it returns.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "PWCallbackClass");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * Refer also to comment in {@link #USER} about HTTP authentication
+     * functions.
+     */
+    public static final String PW_CALLBACK_CLASS = "passwordCallbackClass";
+
+    /**
+     * An application may set an object reference to an object that implements
+     * the {@link javax.security.auth.callback.CallbackHandler} interface.
+     * Only the application can set this property using:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.PW_CALLBACK_REF, anPWCallbackObject);
+     * </pre>
+     * Refer to {@link #PW_CALLBACK_CLASS} for further information about
+     * password callback handling and the priority of the different
+     * methods.
+     * <p/>
+     * Note: every handler that preceeds this handler in the chain can set
+     * this property too. This may be useful on the server side.
+     */
+    public static final String PW_CALLBACK_REF = "passwordCallbackRef";
+
+    /**
+     * The user's name for encryption.
+     * <p/>
+     * The encryption functions uses the public key of this user's certificate
+     * to encrypt the generated symmetric key.
+     * <p/>
+     * If this parameter is not set, then the encryption
+     * function falls back to the {@link #USER} parameter to get the
+     * certificate.
+     * <p/>
+     * If <b>only</b> encryption of the SOAP body data is requested,
+     * it is recommended to use this parameter to define the username.
+     * The application can then use the standard user and password
+     * functions (see example at {@link #USER} to enable HTTP authentication
+     * functions.
+     * <p/>
+     * Encryption only does not authenticate a user / sender, therefore it
+     * does not need a password.
+     * <p/>
+     * Placing the username of the encryption certficate in the WSDD is not
+     * a security risk, because the public key of that certificate is used
+     * only.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ENCYRPTION_USER, "encryptionuser");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String ENCRYPTION_USER = "encryptionUser";
+
+    /**
+     * Specifying this name as {@link ENCRYPTION_USER}
+     * triggers a special action to get the public key to use for encryption.
+     * <p/>
+     * The handler uses the public key of the sender's certificate. Using this
+     * way to define an encryption key simplifies certificate management to
+     * a large extend.
+     */
+    public static final String USE_REQ_SIG_CERT = "useReqSigCert";
+
+    /**
+     * This parameter works in the same way as {@link #PW_CALLBACK_CLASS} but
+     * the Axis WSS4J handler uses it to get the key associated with a key name.
+     */
+    public static final String ENC_CALLBACK_CLASS = "EmbeddedKeyCallbackClass";
+
+    /**
+     * This parameter works in the same way as {@link #PW_CALLBACK_REF} but
+     * the Axis WSS4J handler uses it to get the key associated with a key name.
+     */
+    public static final String ENC_CALLBACK_REF = "EmbeddedKeyCallbackRef";
+
+    /**
+     * Text of the key name that needs to be sent
+     */
+    public static final String ENC_KEY_NAME = "EmbeddedKeyName";
+
+    /**
+     * The name of the crypto propterty file to use for SOAP Signature.
+     * <p/>
+     * The classloader loads this file. Therefore it must be accessible
+     * via the classpath.
+     * <p/>
+     * To locate the implementation of the
+     * {@link org.apache.ws.security.components.crypto.Crypto Crypto}
+     * interface implementation the property file must contain the property
+     * <code>org.apache.ws.security.crypto.provider</code>. The value of
+     * this property is the classname of the implementation class.
+     * <p/>
+     * The following line defines the standard implementation:
+     * <pre>
+     * org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+     * </pre>
+     * The other contents of the property file depend on the implementation
+     * of the {@link org.apache.ws.security.components.crypto.Crypto Crypto}
+     * interface implementation.
+     * <p/>
+     * The property file of the standard implementation
+     * {@link org.apache.ws.security.components.crypto.Merlin} uses
+     * the following properties:
+     * <pre>
+     * org.apache.ws.security.crypto.provider
+     * org.apache.ws.security.crypto.merlin.file
+     * org.apache.ws.security.crypto.merlin.keystore.type
+     * org.apache.ws.security.crypto.merlin.keystore.provider
+     * org.apache.ws.security.crypto.merlin.keystore.password
+     * org.apache.ws.security.crypto.merlin.keystore.alias
+     * org.apache.ws.security.crypto.merlin.cert.provider
+     * </pre>
+     * The entries are:
+     * <ul>
+     * <li> <code>org.apache.ws.security.crypto.provider</code> see
+     * description above
+     * </li>
+     * <li><code>org.apache.ws.security.crypto.merlin.file</code>
+     * The path to the keystore file. At first the classloader tries to load
+     * this file, if this fails the implementations performs a file system
+     * lookup.
+     * </li>
+     * <li><code>org.apache.ws.security.crypto.merlin.keystore.type</code>
+     * The keystore type, for example <code>JKS</code> for the Java key store.
+     * Other keystore type, such as <code>pkcs12</code> are also possible but depend
+     * on the actual <code>Crypto</code> implementation.
+     * </li>
+     * <li><code>org.apache.ws.security.crypto.merlin.keystore.password</code>
+     * The password to read the keystore. If this property is not set, then
+     * the <code>pwcallback</code>property must be defined.
+     * </li>
+     * </ul>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.SIG_PROP_FILE, "myCrypto.properties");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * If a property file is not set and a signature is requested,
+     * the handler throws an <code>AxisFault</code>.
+     */
+    public static final String SIG_PROP_FILE = "signaturePropFile";
+
+    /**
+     * The WSDoAllReceiver handler stores a result <code>Vector</code>
+     * in this property.
+     * <p/>
+     * The vector contains <code>WSDoAllReceiverResult</code> objects
+     * for each chained WSDoAllReceiver handler.
+     */
+    public static final String RECV_RESULTS = "RECV_RESULTS";
+
+    /**
+     * The name of the crypto propterty file to use for SOAP Decryption.
+     * <p/>
+     * Refer to documentation of {@link #SIG_PROP_FILE}.
+     * <p/>
+     * Refer to {@link #SIG_PROP_FILE} for a detail description
+     * about the format and how to use this property file.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.DEC_PROP_FILE, "myCrypto.properties");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * If this parameter is not used, but the signature crypto property
+     * file is defined (combined Encryption/Signature action), then the
+     * encryption function uses that file. Otherwise the handler throws
+     * an <code>AxisFault</code>.
+     */
+    public static final String DEC_PROP_FILE = "decryptionPropFile";
+
+    /**
+     * Specific parameter for UsernameToken action to define the encoding
+     * of the passowrd.
+     * <p/>
+     * The parameter can be set to either {@link WSConstants#PW_DIGEST}
+     * or to {@link WSConstants#PW_TEXT}.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * The default setting is PW_DIGEST.
+     */
+    public static final String PASSWORD_TYPE = "passwordType";
+
+    /**
+     * Parameter to generate additional elements in <code>UsernameToken</code>.
+     * <p/>
+     * The value of this parameter is a list of element names that are added
+     * to the UsernameToken. The names of the list a separated by spaces.
+     * <p/>
+     * The list may containe the names <code>nonce</code> and
+     * <code>created</code> only. Use this option if the password type is
+     * <code>passwordText</code> and the handler shall add the <code>Nonce</code>
+     * and/or <code>Created</code> elements.
+     */
+    public static final String ADD_UT_ELEMENTS = "addUTElements";
+
+    /**
+     * Defines which key identifier type to use. The WS-Security specifications
+     * recommends to use the identifier type <code>IssuerSerial</code>. For
+     * possible signature key identifier types refer to
+     * {@link #keyIdentifier}. For signature <code>IssuerSerial</code>
+     * and <code>DirectReference</code> are valid only.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String SIG_KEY_ID = "signatureKeyIdentifier";
+
+    /**
+     * Defines which signature algorithm to use. Currently this
+     * parameter is ignored - SHA1RSA is the only supported algorithm,
+     * will be enhanced soon.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.SIG_ALGO, "SHA1RSA");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String SIG_ALGO = "signatureAlgorithm";
+
+    /**
+     * Parameter to define which parts of the request shall be signed.
+     * <p/>
+     * Refer to {@link #ENCRYPTION_PARTS} for a detailed description of
+     * the format of the value string.
+     * <p/>
+     * If this parameter is not specified the handler signs the SOAP Body
+     * by default.
+     * <p/>
+     * The WS Security specifications define several formats to transfer the
+     * signature tokens (certificates) or  references to these tokens.
+     * Thus, the plain element name <code>Token</code>
+     * signs the token and takes care of the different format.
+     * <p/>
+     * To sign the SOAP body <b>and</b> the signature token the value of this
+     * parameter must contain:
+     * <pre>
+     * &lt;parameter name="signatureParts"
+     *   value="{}{http://schemas.xmlsoap.org/soap/envelope/}Body; Token" />
+     * </pre>
+     * To specify an element without a namespace use the string
+     * <code>Null</code> as the namespace name (this is a case sensitive
+     * string)
+     * <p/>
+     * If there is no other element in the request with a local name of
+     * <code>Body</code> then the SOAP namespace identifier can be empty
+     * (<code>{}</code>).
+     */
+    public static final String SIGNATURE_PARTS = "signatureParts";
+
+    /**
+     * The name of the crypto propterty file to use for SOAP Encryption.
+     * <p/>
+     * Refer to documentation of {@link #SIG_PROP_FILE}.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ENC_PROP_FILE, "myCrypto.properties");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     * <p/>
+     * If this parameter is not used, but the signature crypto property
+     * file is defined (combined Encryption/Signature action), then the
+     * encryption function uses signature property file. Otherwise the
+     * handler throws an <code>AxisFault</code>.
+     */
+    public static final String ENC_PROP_FILE = "encryptionPropFile";
+
+    /**
+     * Defines which key identifier type to use. The WS-Security specifications
+     * recommends to use the identifier type <code>IssuerSerial</code>. For
+     * possible encryption key identifier types refer to
+     * {@link #keyIdentifier}. For encryption <code>IssuerSerial</code>
+     * and <code>X509KeyIdentifier</code> are valid only.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String ENC_KEY_ID = "encryptionKeyIdentifier";
+
+    /**
+     * Defines which symmetric encryption algorithm to use. WSS4J supports the
+     * following alorithms: {@link WSConstants#TRIPLE_DES},
+     * {@link WSConstants#AES_128}, {@link WSConstants#AES_256},
+     * and {@link WSConstants#AES_192}. Except for AES 192 all of these
+     * algorithms are required by the XML Encryption specification.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ENC_SYM_ALGO, WSConstants.AES_256);
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String ENC_SYM_ALGO = "encryptionSymAlgorithm";
+
+    /**
+     * Defines which algorithm to use to encrypt the generated symmetric key.
+     * Currently WSS4J supports {@link WSConstants#KEYTRANSPORT_RSA15} only.
+     * <p/>
+     * The application may set this parameter using the following method:
+     * <pre>
+     * call.setProperty(WSHandlerConstants.ENC_KEY_TRANSPORT, "RSA15");
+     * </pre>
+     * However, the parameter in the WSDD deployment file overwrites the
+     * property setting (deployment setting overwrites application setting).
+     */
+    public static final String ENC_KEY_TRANSPORT =
+            "encryptionKeyTransportAlgorithm";
+
+    /**
+     * Parameter to define which parts of the request shall be encrypted.
+     * <p/>
+     * The value of this parameter is a list of semi-colon separated
+     * element names that identify the elements to encrypt. An encryption mode
+     * specifier and a namespace identification, each inside a pair of curly
+     * brackets, may preceed each element name.
+     * <p/>
+     * The encryption mode specifier is either <code>{Content}</code> or
+     * <code>{Element}</code>. Please refer to the W3C XML Encryption
+     * specification about the differences between Element and Content
+     * encryption. The encryption mode defaults to <code>Content</code>
+     * if it is omitted. Example of a list:
+     * <pre>
+     * &lt;parameter name="encryptionParts"
+     *   value="{Content}{http://example.org/paymentv2}CreditCard;
+     *             {Element}{}UserName" />
+     * </pre>
+     * The the first entry of the list identifies the element
+     * <code>CreditCard</code> in the namespace
+     * <code>http://example.org/paymentv2</code>, and will encrypt its content.
+     * Be aware that the element name, the namespace identifier, and the
+     * encryption modifier are case sensitive.
+     * <p/>
+     * The encryption modifier and the namespace identifier can be ommited.
+     * In this case the encryption mode defaults to <code>Content</code> and
+     * the namespace is set to the SOAP namespace.
+     * <p/>
+     * An empty encryption mode defaults to <code>Content</code>, an empty
+     * namespace identifier defaults to the SOAP namespace.
+     * The second line of the example defines <code>Element</code> as
+     * encryption mode for an <code>UserName</code> element in the SOAP
+     * namespace.
+     * <p/>
+     * To specify an element without a namespace use the string
+     * <code>Null</code> as the namespace name (this is a case sensitive
+     * string)
+     * <p/>
+     * If no list is specified, the handler encrypts the SOAP Body in
+     * <code>Content</code> mode by default.
+     */
+    public static final String ENCRYPTION_PARTS = "encryptionParts";
+
+    /**
+     * The name of the SAML Issuer factory property file.
+     * The classloader loads this file. Therefore it must be accessible
+     * via the classpath.
+     */
+    public static final String SAML_PROP_FILE = "samlPropFile";
+
+    /**
+     * Time-To-Live is the time difference between creation and expiry time in
+     * the WSS Timestamp.
+     * The time-to-live in seconds. After this time the SOAP request is
+     * invalid (at least the security data shall be treated this way).
+     * <p/>
+     * If this parameter is not defined, contains a value less or equal
+     * zero, or an illegal format the handlers use a default TTL of
+     * 300 seconds (5 minutes).
+     */
+    public static final String TTL_TIMESTAMP = "timeToLive";
+
+    /**
+     * Whether to enable signatureConfirmation or not
+     * By default signatureConfirmation is enabled
+     */
+    public static final String ENABLE_SIGNATURE_CONFIRMATION = "enableSignatureConfirmation";
+    
+    /**
+     * Should timestamps have precision in milliseconds
+     */
+    public static final String TIMESTAMP_PRECISION = "precisionInMilliseconds";
+    
+    /**
+     * Set the value of this parameter to true to enable strict timestamp
+     * handling.
+     * 
+     * Strict Timestamp handling: throw an exception if a Timestamp contains
+     * an <code>Expires</code> element and the semantics of the request are
+     * expired, i.e. the current time at the receiver is past the expires time. 
+     */
+    public static final String TIMESTAMP_STRICT = "timestampStrict";
+    
+    /**
+     * Define the parameter values to set the key identifier types. These are:
+     * <ul>
+     * <li><code>DirectReference</code> for {@link WSConstants#BST_DIRECT_REFERENCE}
+     * </li>
+     * <li><code>IssuerSerial</code> for {@link WSConstants#ISSUER_SERIAL}
+     * </li>
+     * <li><code>X509KeyIdentifier</code> for {@link WSConstants#X509_KEY_IDENTIFIER}
+     * </li>
+     * <li><code>SKIKeyIdentifier</code> for {@link WSConstants#SKI_KEY_IDENTIFIER}
+     * </li>
+     * <li><code>EmbeddedKeyName</code> for {@link WSConstants#EMBEDDED_KEYNAME}
+     * </li>
+     * <li><code>Thumbprint</code> for {@link WSConstants#THUMBPRINT}
+     * </li>
+     * </ul
+     * See {@link #SIG_KEY_ID} {@link #ENC_KEY_ID}.
+     */
+    public static Map keyIdentifier = new Hashtable();
+
+    static {
+        keyIdentifier.put("DirectReference",
+                new Integer(WSConstants.BST_DIRECT_REFERENCE));
+        keyIdentifier.put("IssuerSerial",
+                new Integer(WSConstants.ISSUER_SERIAL));
+        keyIdentifier.put("X509KeyIdentifier",
+                new Integer(WSConstants.X509_KEY_IDENTIFIER));
+        keyIdentifier.put("SKIKeyIdentifier",
+                new Integer(WSConstants.SKI_KEY_IDENTIFIER));
+        keyIdentifier.put("EmbeddedKeyName",
+                new Integer(WSConstants.EMBEDDED_KEYNAME));
+        keyIdentifier.put("Thumbprint",
+                new Integer(WSConstants.THUMBPRINT_IDENTIFIER));
+    }
+    /*
+     * internally used property names to store values inside the message context
+     * that must have the same livetime as a message (request/response model).
+     */
+    public static final String SEND_SIGV = "_sendSignatureValues_";
+    public static final String SIG_CONF_DONE = "_sigConfDone_";
+}
+
diff --git a/src/org/apache/ws/security/handler/WSHandlerResult.java b/src/org/apache/ws/security/handler/WSHandlerResult.java
new file mode 100644
index 0000000..4975a7a
--- /dev/null
+++ b/src/org/apache/ws/security/handler/WSHandlerResult.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.handler;
+
+import java.util.Vector;
+
+/**
+ * @author Werner Dittmann (Werner.Dittmann@Siemens.com)
+ */
+public class WSHandlerResult {
+    private String actor;
+    private Vector wsSecurityResults;
+
+    /**
+     * constructor
+     * @param actor
+     * @param wsResults
+     */ 
+    public WSHandlerResult(String actor, Vector wsResults) {
+        this.actor = actor;
+        this.wsSecurityResults = wsResults;
+    }
+
+    /**
+     * gets the actor
+     * @return actor
+     */
+    public String getActor() {
+        return actor;
+    }
+
+    /**
+     * gets the the security results
+     * @return vector
+     */
+    public Vector getResults() {
+        return wsSecurityResults;
+    }
+}
diff --git a/src/org/apache/ws/security/handler/WSS4JHandler.java b/src/org/apache/ws/security/handler/WSS4JHandler.java
new file mode 100755
index 0000000..685d516
--- /dev/null
+++ b/src/org/apache/ws/security/handler/WSS4JHandler.java
@@ -0,0 +1,554 @@
+/*
+* Copyright  2003-2004 The Apache Software Foundation.
+*
+*  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.apache.ws.security.handler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.rpc.Call;
+import javax.xml.rpc.JAXRPCException;
+import javax.xml.rpc.handler.Handler;
+import javax.xml.rpc.handler.HandlerInfo;
+import javax.xml.rpc.handler.MessageContext;
+import javax.xml.rpc.handler.soap.SOAPMessageContext;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.soap.SOAPPart;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * Merged and converted the the axis handlers WSDoAllReceiver and WSDoAllSender
+ * into a single JAX-RPC Handler. All the axis dependencies are removed.
+ *
+ * @author Venkat Reddy (vreddyp@gmail.com).
+ */
+public class WSS4JHandler extends WSHandler implements Handler {
+    private HandlerInfo handlerInfo;
+    
+    private static Log log = LogFactory.getLog(WSS4JHandler.class.getName());
+
+    private boolean doDebug = log.isDebugEnabled();;
+
+    static final String DEPLOYMENT = "deployment";
+    static final String CLIENT_DEPLOYMENT = "client";
+    static final String SERVER_DEPLOYMENT = "server";
+    static final String FLOW = "flow";
+    static final String REQUEST_ONLY = "request-only";
+    static final String RESPONSE_ONLY = "response-only";
+    static final String ALLOW_FORM_OPTIMIZATION = "axis.form.optimization";
+
+    /**
+     * Initializes the instance of the handler.
+     */
+    public void init(HandlerInfo hi) {
+        handlerInfo = hi;
+    }
+
+    /**
+     * Destroys the Handler instance.
+     */
+    public void destroy() {
+    }
+
+    public QName[] getHeaders() {
+        return handlerInfo.getHeaders();
+    }
+
+    public boolean handleRequest(MessageContext mc) {
+        mc.setProperty(ALLOW_FORM_OPTIMIZATION,
+            Boolean.TRUE);
+        try {
+            return processMessage(mc, true);
+        } catch (WSSecurityException e) {
+            throw new JAXRPCException(e);
+        }
+    }
+
+    public boolean handleResponse(MessageContext mc) {
+        mc.setProperty(ALLOW_FORM_OPTIMIZATION,
+            Boolean.TRUE);
+        try {
+            return processMessage(mc, false);
+        } catch (WSSecurityException e) {
+            throw new JAXRPCException(e);
+        }
+    }
+
+    /**
+     * Handles SOAP Faults that may occur during message processing
+     */
+    public boolean handleFault(MessageContext mc) {
+        if (doDebug) {
+            log.debug("Entered handleFault");
+        }
+        return true;
+    }
+
+    /**
+     * Switch for transfering control to doReceiver and doSender
+     */
+    public boolean processMessage(MessageContext mc, boolean isRequestMessage) throws WSSecurityException {
+
+        RequestData reqData = new RequestData();
+        reqData.setMsgContext(mc);
+
+        doDebug = log.isDebugEnabled();
+        String deployment = null;
+        String handleFlow = null;
+
+        if ((deployment = (String) getOption(DEPLOYMENT)) == null) {
+            deployment = (String) mc.getProperty(DEPLOYMENT);
+        }
+        if (deployment == null) {
+            throw new JAXRPCException("WSS4JHandler.processMessage: No deployment defined");
+        }
+        if ((handleFlow = (String) getOption(FLOW)) == null) {
+            handleFlow = (String) mc.getProperty(FLOW);
+        }
+        if (handleFlow == null) {
+            handleFlow = "";
+        }
+
+        // call doSender if we are -
+        // (handling request and client-side deployment) or (handling response and server-side deployment).
+        // call doReceiver if we are -
+        // (handling request and server-side deployment) or (handling response and client-side deployment).
+
+        boolean needsHandling = ( isRequestMessage && !handleFlow.equals(RESPONSE_ONLY)) ||
+                                (!isRequestMessage && !handleFlow.equals(REQUEST_ONLY));
+        try {
+            if (deployment.equals(CLIENT_DEPLOYMENT) ^ isRequestMessage) {
+                if (needsHandling) {
+                    return doReceiver(mc, reqData, isRequestMessage);
+                }
+            } else {
+                if (needsHandling) {
+                    return doSender(mc, reqData, isRequestMessage);
+                }
+            }
+        } finally {
+            reqData.clear();
+            reqData = null;
+        }
+        return true;
+    }
+
+    /**
+     * Handles incoming web service requests and outgoing responses
+     */
+    public boolean doSender(MessageContext mc, RequestData reqData, boolean isRequest) throws WSSecurityException {
+
+        reqData.getSignatureParts().removeAllElements();
+        reqData.getEncryptParts().removeAllElements();
+        reqData.setNoSerialization(false);
+        /*
+        * Get the action first.
+        */
+        Vector actions = new Vector();
+        String action = (String) getOption(WSHandlerConstants.SEND + '.' + WSHandlerConstants.ACTION);
+        if (action == null) {
+            if ((action = (String) getOption(WSHandlerConstants.ACTION)) == null) {
+                action = (String) mc.getProperty(WSHandlerConstants.ACTION);
+            }
+        }
+        if (action == null) {
+            throw new JAXRPCException("WSS4JHandler: No action defined");
+        }
+        int doAction = WSSecurityUtil.decodeAction(action, actions);
+        if (doAction == WSConstants.NO_SECURITY) {
+            return true;
+        }
+        
+        /*
+        * For every action we need a username, so get this now. The username
+        * defined in the deployment descriptor takes precedence.
+        */
+       reqData.setUsername((String) getOption(WSHandlerConstants.USER));
+        if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+            reqData.setUsername((String) mc.getProperty(WSHandlerConstants.USER));
+            mc.setProperty(WSHandlerConstants.USER, null);
+        }
+
+        /*
+        * Now we perform some set-up for UsernameToken and Signature
+        * functions. No need to do it for encryption only. Check if username
+        * is available and then get a passowrd.
+        */
+        if ((doAction & (WSConstants.SIGN | WSConstants.UT | WSConstants.UT_SIGN)) != 0) {
+            /*
+            * We need a username - if none throw an JAXRPCException. For encryption
+            * there is a specific parameter to get a username.
+            */
+            if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+                throw new JAXRPCException("WSS4JHandler: Empty username for specified action");
+            }
+        }
+        if (doDebug) {
+            log.debug("Action: " + doAction);
+            log.debug("Actor: " + reqData.getActor());
+        }
+        /*
+        * Now get the SOAP part from the request message and convert it into a
+        * Document.
+        *
+        * This forces Axis to serialize the SOAP request into FORM_STRING.
+        * This string is converted into a document.
+        *
+        * During the FORM_STRING serialization Axis performs multi-ref of
+        * complex data types (if requested), generates and inserts references
+        * for attachements and so on. The resulting Document MUST be the
+        * complete and final SOAP request as Axis would send it over the wire.
+        * Therefore this must shall be the last (or only) handler in a chain.
+        *
+        * Now we can perform our security operations on this request.
+        */
+        Document doc = null;
+        SOAPMessage message = ((SOAPMessageContext)mc).getMessage();
+        Boolean propFormOptimization = (Boolean)mc.getProperty("axis.form.optimization");
+        log.debug("Form optimzation: " + propFormOptimization);
+        /*
+        * If the message context property conatins a document then this is a
+        * chained handler.
+        */
+        SOAPPart sPart = message.getSOAPPart();
+        if ((doc = (Document) mc.getProperty(WSHandlerConstants.SND_SECURITY))
+                == null) {
+            try {
+                doc = messageToDocument(message);
+            } catch (Exception e) {
+                throw new JAXRPCException("WSS4JHandler: cannot get SOAP envlope from message" + e);
+            }
+        }
+        if (doDebug) {
+            log.debug("WSS4JHandler: orginal SOAP request: ");
+            log.debug(org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc));
+        }
+        doSenderAction(doAction, doc, reqData, actions, isRequest);
+ 
+        /*
+        * If required convert the resulting document into a message first. The
+        * outputDOM() method performs the necessary c14n call. After that we
+        * extract it as a string for further processing.
+        *
+        * Set the resulting byte array as the new SOAP message.
+        *
+        * If noSerialization is false, this handler shall be the last (or only)
+        * one in a handler chain. If noSerialization is true, just set the
+        * processed Document in the transfer property. The next Axis WSS4J
+        * handler takes it and performs additional security processing steps.
+        *
+        */
+        if (reqData.isNoSerialization()) {
+            mc.setProperty(WSHandlerConstants.SND_SECURITY, doc);
+        } else {
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            XMLUtils.outputDOM(doc, os, true);
+            if (doDebug) {
+                String osStr = null;
+                try {
+                    osStr = os.toString("UTF-8");
+                } catch (UnsupportedEncodingException e) {
+                    osStr = os.toString();
+                }
+                log.debug("Send request:");
+                log.debug(osStr);
+            }
+
+            try {
+                sPart.setContent(new StreamSource(new ByteArrayInputStream(os.toByteArray())));
+            } catch (SOAPException se) {
+                throw new JAXRPCException("Couldn't set content on SOAPPart" + se.getMessage());
+            }
+            mc.setProperty(WSHandlerConstants.SND_SECURITY, null);
+        }
+        if (doDebug) {
+            log.debug("WSS4JHandler: exit invoke()");
+        }
+        return true;
+    }
+
+    /**
+     * handle responses
+     *
+     * @param mc
+     * @param reqData
+     * @return
+     * @throws WSSecurityException
+     */
+    public boolean doReceiver(MessageContext mc, RequestData reqData, boolean isRequest) throws WSSecurityException {
+
+        Vector actions = new Vector();
+        String action = (String) getOption(WSHandlerConstants.RECEIVE + '.' + WSHandlerConstants.ACTION);
+        if (action == null) {
+            if ((action = (String) getOption(WSHandlerConstants.ACTION)) == null) {
+                action = (String) mc.getProperty(WSHandlerConstants.ACTION);
+            }
+        }
+        if (action == null) {
+            throw new JAXRPCException("WSS4JHandler: No action defined");
+        }
+        int doAction = WSSecurityUtil.decodeAction(action, actions);
+
+        String actor = (String) getOption(WSHandlerConstants.ACTOR);
+
+        SOAPMessage message = ((SOAPMessageContext)mc).getMessage();
+        SOAPPart sPart = message.getSOAPPart();
+        Document doc = null;
+        try {
+            doc = messageToDocument(message);
+        } catch (Exception ex) {
+            throw new JAXRPCException("WSS4JHandler: cannot convert into document",
+                    ex);
+        }
+        /*
+        * Check if it's a fault. Don't process faults.
+        *
+        */
+        SOAPConstants soapConstants =
+                WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+        if (WSSecurityUtil
+                .findElement(doc.getDocumentElement(),
+                        "Fault",
+                        soapConstants.getEnvelopeURI())
+                != null) {
+            return false;
+        }
+
+        /*
+        * To check a UsernameToken or to decrypt an encrypted message we need
+        * a password.
+        */
+        CallbackHandler cbHandler = null;
+        if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
+            cbHandler = getPasswordCB(reqData);
+        }
+
+        /*
+        * Get and check the Signature specific parameters first because they
+        * may be used for encryption too.
+        */
+        doReceiverAction(doAction, reqData);
+
+        Vector wsResult = null;
+        try {
+            wsResult =
+                    secEngine.processSecurityHeader(doc,
+                            actor,
+                            cbHandler,
+                            reqData.getSigCrypto(),
+                            reqData.getDecCrypto());
+        } catch (WSSecurityException ex) {
+            ex.printStackTrace();
+            throw new JAXRPCException("WSS4JHandler: security processing failed",
+                    ex);
+        }
+        if (wsResult == null) {			// no security header found
+            if (doAction == WSConstants.NO_SECURITY) {
+                return true;
+            } else {
+                throw new JAXRPCException("WSS4JHandler: Request does not contain required Security header");
+            }
+        }
+        if (reqData.getWssConfig().isEnableSignatureConfirmation() && !isRequest) {
+            checkSignatureConfirmation(reqData, wsResult);
+        }
+
+        /*
+        * If we had some security processing, get the original
+        * SOAP part of Axis' message and replace it with new SOAP
+        * part. This new part may contain decrypted elements.
+        */
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        XMLUtils.outputDOM(doc, os, true);
+        try {
+            sPart.setContent(new StreamSource(new ByteArrayInputStream(os.toByteArray())));
+        } catch (SOAPException se) {
+            throw new JAXRPCException("Couldn't set content on SOAPPart" + se.getMessage());
+        }
+
+        if (doDebug) {
+            log.debug("Processed received SOAP request");
+        }
+
+        /*
+        * After setting the new current message, probably modified because
+        * of decryption, we need to locate the security header. That is,
+        * we force Axis (with getSOAPEnvelope()) to parse the string, build
+        * the new header. Then we examine, look up the security header
+        * and set the header as processed.
+        *
+        * Please note: find all header elements that contain the same
+        * actor that was given to processSecurityHeader(). Then
+        * check if there is a security header with this actor.
+        */
+
+        SOAPHeader sHeader = null;
+        try {
+            sHeader = message.getSOAPPart().getEnvelope().getHeader();
+        } catch (Exception ex) {
+            throw new JAXRPCException("WSS4JHandler: cannot get SOAP header after security processing", ex);
+        }
+
+        Iterator headers = sHeader.examineHeaderElements(actor);
+
+        SOAPHeaderElement headerElement = null;
+        while (headers.hasNext()) {
+            SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
+            if (hE.getElementName().getLocalName().equals(WSConstants.WSSE_LN)
+                    && ((Node) hE).getNamespaceURI().equals(WSConstants.WSSE_NS)) {
+                headerElement = hE;
+                break;
+            }
+        }
+
+        /* JAXRPC conversion changes */
+        headerElement.setMustUnderstand(false); // is this sufficient?
+
+        /*
+        * Now we can check the certificate used to sign the message.
+        * In the following implementation the certificate is only trusted
+        * if either it itself or the certificate of the issuer is installed
+        * in the keystore.
+        *
+        * Note: the method verifyTrust(X509Certificate) allows custom
+        * implementations with other validation algorithms for subclasses.
+        */
+
+        // Extract the signature action result from the action vector
+
+        WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.SIGN);
+
+        if (actionResult != null) {
+            X509Certificate returnCert = actionResult.getCertificate();
+
+            if (returnCert != null) {
+                if (!verifyTrust(returnCert, reqData)) {
+                    throw new JAXRPCException("WSS4JHandler: The certificate used for the signature is not trusted");
+                }
+            }
+        }
+
+        /*
+        * Perform further checks on the timestamp that was transmitted in the header.
+        * In the following implementation the timestamp is valid if it was
+        * created after (now-ttl), where ttl is set on server side, not by the client.
+        *
+        * Note: the method verifyTimestamp(Timestamp) allows custom
+        * implementations with other validation algorithms for subclasses.
+        */
+
+        // Extract the timestamp action result from the action vector
+        actionResult = WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
+
+        if (actionResult != null) {
+            Timestamp timestamp = actionResult.getTimestamp();
+
+            if (timestamp != null && reqData.getWssConfig().isTimeStampStrict()) {
+                if (!verifyTimestamp(timestamp, decodeTimeToLive(reqData))) {
+                    throw new JAXRPCException("WSS4JHandler: The timestamp could not be validated");
+                }
+            }
+        }
+
+        /*
+        * now check the security actions: do they match, in right order?
+        */
+        if (!checkReceiverResults(wsResult, actions)) {
+            throw new JAXRPCException("WSS4JHandler: security processing failed (actions mismatch)");
+        }
+
+        /*
+        * All ok up to this point. Now construct and setup the
+        * security result structure. The service may fetch this
+        * and check it.
+        */
+        Vector results = null;
+        if ((results = (Vector) mc.getProperty(WSHandlerConstants.RECV_RESULTS))
+                == null) {
+            results = new Vector();
+            mc.setProperty(WSHandlerConstants.RECV_RESULTS, results);
+        }
+        WSHandlerResult rResult =
+                new WSHandlerResult(actor,
+                        wsResult);
+        results.add(0, rResult);
+        if (doDebug) {
+            log.debug("WSS4JHandler: exit invoke()");
+        }
+
+        return true;
+    }
+
+    /**
+     * Utility method to convert SOAPMessage to org.w3c.dom.Document
+     */
+    public static Document messageToDocument(SOAPMessage message) {
+        try {
+            Source content = message.getSOAPPart().getContent();
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            dbf.setNamespaceAware(true);
+            DocumentBuilder builder = dbf.newDocumentBuilder();
+            return builder.parse(org.apache.ws.security.util.XMLUtils.sourceToInputSource(content));
+        } catch (Exception ex) {
+            throw new JAXRPCException("messageToDocument: cannot convert SOAPMessage into Document", ex);
+        }
+    }
+
+    public Object getOption(String key) {
+        return handlerInfo.getHandlerConfig().get(key);
+    }
+
+    public Object getProperty(Object msgContext, String key) {
+        return ((MessageContext)msgContext).getProperty(key);
+    }
+
+    public void setProperty(Object msgContext, String key, Object value) {
+        ((MessageContext)msgContext).setProperty(key, value);
+    }
+
+    public String getPassword(Object msgContext) {
+        return (String) ((MessageContext)msgContext).getProperty(Call.PASSWORD_PROPERTY);
+    }
+
+    public void setPassword(Object msgContext, String password) {
+        ((MessageContext)msgContext).setProperty(Call.PASSWORD_PROPERTY, password);
+    }
+}
diff --git a/src/org/apache/ws/security/message/EnvelopeIdResolver.java b/src/org/apache/ws/security/message/EnvelopeIdResolver.java
new file mode 100644
index 0000000..f8c04b3
--- /dev/null
+++ b/src/org/apache/ws/security/message/EnvelopeIdResolver.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.signature.XMLSignatureInput;
+import org.apache.xml.security.utils.resolver.ResourceResolverException;
+import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
+import org.apache.xml.utils.URI;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * XML-Security resolver that is used for resolving same-document URI like URI="#id".
+ * It is desgined to only work with SOAPEnvelopes.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class EnvelopeIdResolver extends ResourceResolverSpi {
+    private static Log log =
+            LogFactory.getLog(EnvelopeIdResolver.class.getName());
+
+    private static EnvelopeIdResolver resolver = null;
+
+    private boolean doDebug = false;
+
+    /**
+     * Singleton instance of the resolver.
+     * <p/>
+     *
+     * @return TODO
+     */
+    public synchronized static ResourceResolverSpi getInstance() {
+        if (resolver == null) {
+            resolver = new EnvelopeIdResolver();
+        }
+        return resolver;
+    }
+
+    private EnvelopeIdResolver() {
+    }
+
+    /**
+     * This is the workhorse method used to resolve resources.
+     * <p/>
+     *
+     * @param uri
+     * @param BaseURI
+     * @return TODO
+     * @throws ResourceResolverException
+     */
+    public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
+            throws ResourceResolverException {
+
+        doDebug = log.isDebugEnabled();
+
+        String uriNodeValue = uri.getNodeValue();
+
+        if (doDebug) {
+            log.debug("enter engineResolve, look for: " + uriNodeValue);
+        }
+
+        Document doc = uri.getOwnerDocument();
+
+        /*
+         * URI="#chapter1"
+         * Identifies a node-set containing the element with ID attribute
+         * value 'chapter1' of the XML resource containing the signature.
+         * XML Signature (and its applications) modify this node-set to
+         * include the element plus all descendents including namespaces and
+         * attributes -- but not comments.
+         */
+         
+        /*
+         * First lookup the SOAP Body element (processed by default) and
+         * check if it contains an Id and if it matches
+         */
+        String id = uriNodeValue.substring(1);
+        SOAPConstants sc = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+        Element selectedElem = WSSecurityUtil.findBodyElement(doc, sc);
+        if (selectedElem == null) {
+            throw new ResourceResolverException("generic.EmptyMessage",
+                    new Object[]{"Body element not found"},
+                    uri,
+                    BaseURI);
+        }
+        String cId = selectedElem.getAttributeNS(WSConstants.WSU_NS, "Id");
+
+        /*
+         * If Body Id match fails, look for a generic Id (without a namespace)
+         * that matches the URI. If that lookup fails, try to get a namespace
+         * qualified Id that matches the URI.
+         */
+        if (!id.equals(cId)) {
+            cId = null;
+            if ((selectedElem = WSSecurityUtil.getElementByWsuId(doc, uriNodeValue)) != null) {
+                cId = selectedElem.getAttribute("Id");
+            } else if ((selectedElem = WSSecurityUtil.getElementByGenId(doc, uriNodeValue)) != null) {
+                cId = selectedElem.getAttribute("Id");
+            }
+            if (cId == null) {
+                throw new ResourceResolverException("generic.EmptyMessage",
+                        new Object[]{"Id not found"},
+                        uri,
+                        BaseURI);
+            }
+        }
+
+        XMLSignatureInput result = new XMLSignatureInput(selectedElem);
+        result.setMIMEType("text/xml");
+        try {
+            URI uriNew = new URI(new URI(BaseURI), uri.getNodeValue());
+            result.setSourceURI(uriNew.toString());
+        } catch (URI.MalformedURIException ex) {
+            result.setSourceURI(BaseURI);
+        }
+        if (doDebug) {
+            log.debug("exit engineResolve, result: " + result);
+        }
+        return result;
+    }
+
+    /**
+     * This method helps the ResourceResolver to decide whether a
+     * ResourceResolverSpi is able to perform the requested action.
+     * <p/>
+     *
+     * @param uri
+     * @param BaseURI
+     * @return TODO
+     */
+    public boolean engineCanResolve(Attr uri, String BaseURI) {
+        if (uri == null) {
+            return false;
+        }
+        String uriNodeValue = uri.getNodeValue();
+        return uriNodeValue.startsWith("#");
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSAddSignatureConfirmation.java b/src/org/apache/ws/security/message/WSAddSignatureConfirmation.java
new file mode 100644
index 0000000..d1c511b
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSAddSignatureConfirmation.java
@@ -0,0 +1,131 @@
+/*

+ * Copyright  2003-2005 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.message.token.SignatureConfirmation;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+/**

+ * Builds a WS SignatureConfirmation and inserts it into the SOAP Envelope.

+ * 

+ * @author Werner Dittmann (Werner.Dittmann@t-online.de).

+ */

+

+public class WSAddSignatureConfirmation extends WSBaseMessage {

+    private static Log log = LogFactory.getLog(WSAddSignatureConfirmation.class

+            .getName());

+

+    private SignatureConfirmation sc = null;

+

+    private String id = null;

+

+    /**

+     * Constructor.

+     * 

+     * @deprecated replaced by {@link WSSecSignatureConfirmation#WSSecSignatureConfirmation()}

+     */

+    public WSAddSignatureConfirmation() {

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param actor

+     *            the name of the actor of the <code>wsse:Security</code>

+     *            header

+     * 

+     * @deprecated replaced by {@link WSSecSignatureConfirmation#WSSecSignatureConfirmation()}

+     *             and {@link WSSecHeader} for actor specification.

+     */

+    public WSAddSignatureConfirmation(String actor) {

+        super(actor);

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param actor

+     *            The name of the actor of the <code>wsse:Security</code>

+     *            header

+     * @param mu

+     *            Set <code>mustUnderstand</code> to true or false

+     * 

+     * @deprecated replaced by {@link WSSecSignatureConfirmation#WSSecSignatureConfirmation()}

+     *             and {@link WSSecHeader} for actor and mustunderstand

+     *             specification.

+     */

+    public WSAddSignatureConfirmation(String actor, boolean mu) {

+        super(actor, mu);

+    }

+

+    /**

+     * Adds a new <code>SignatureConfirmation</code> to a soap envelope.

+     * 

+     * A complete <code>SignatureConfirmation</code> is constructed and added

+     * to the <code>wsse:Security</code> header.

+     * 

+     * @param doc

+     *            The SOAP enevlope as W3C document

+     * @param sigVal

+     *            the Signature value. This will be the content of the "Value"

+     *            attribute.

+     * @return Document with SignatureConfirmation added

+     * 

+     * @deprecated replaced by

+     *             {@link WSSecSignatureConfirmation#build(Document, byte[], WSSecHeader)}

+     */

+    public Document build(Document doc, byte[] sigVal) {

+        log.debug("Begin add signature confirmation...");

+        Element securityHeader = insertSecurityHeader(doc);

+        sc = new SignatureConfirmation(doc, sigVal);

+        if (id != null) {

+            sc.setID(id);

+        }

+        WSSecurityUtil.prependChildElement(doc, securityHeader,

+                sc.getElement(), true);

+        sc = null;

+        return doc;

+    }

+

+    /**

+     * Set the wsu:Id value of the SignatureConfirmation

+     * 

+     * @param id

+     * 

+     * @deprecated no replacement, id is created by default in

+     *             {@link WSSecSignatureConfirmation}

+     */

+    public void setId(String id) {

+        this.id = id;

+    }

+

+    /**

+     * Get the wsu:Id value of the SignatureConfirmation

+     * 

+     * @return Returns the wsu:id value

+     * 

+     * @deprecated replaced by {@link WSSecSignatureConfirmation#getId()}

+     */

+    public String getId() {

+        return id;

+    }

+}

diff --git a/src/org/apache/ws/security/message/WSAddTimestamp.java b/src/org/apache/ws/security/message/WSAddTimestamp.java
new file mode 100644
index 0000000..5aaa7c4
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSAddTimestamp.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a WS Timestamp and inserts it into the SOAP Envelope. Refer to the WS
+ * specification 1.0. chapter 10 / appendix A.2
+ * 
+ * @author Christof Soehngen (Christof.Soehngen@syracom.de).
+ */
+
+public class WSAddTimestamp extends WSBaseMessage {
+    private static Log log = LogFactory.getLog(WSAddTimestamp.class.getName());
+
+    private Timestamp ts = null;
+
+    private String id = null;
+
+    /**
+     * Constructor.
+     * 
+     * @deprecated replaced by {@link WSSecTimestamp#WSSecTimestamp()}
+     */
+    public WSAddTimestamp() {
+    }
+
+    /**
+     * Constructor. <p/>
+     * 
+     * @param actor
+     *            the name of the actor of the <code>wsse:Security</code>
+     *            header
+     * 
+     * @deprecated replaced by {@link WSSecTimestamp#WSSecTimestamp()} and
+     *             {@link WSSecHeader} for actor specification.
+     */
+    public WSAddTimestamp(String actor) {
+        super(actor);
+    }
+
+    /**
+     * Constructor. <p/>
+     * 
+     * @param actor
+     *            The name of the actor of the <code>wsse:Security</code>
+     *            header
+     * @param mu
+     *            Set <code>mustUnderstand</code> to true or false
+     * @deprecated replaced by {@link WSSecTimestamp#WSSecTimestamp()} and
+     *             {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSAddTimestamp(String actor, boolean mu) {
+        super(actor, mu);
+    }
+
+    /**
+     * Adds a new <code>Timestamp</code> to a soap envelope.
+     * 
+     * A complete <code>Timestamp</code> is constructed and added to the
+     * <code>wsse:Security</code> header.
+     * 
+     * @param doc
+     *            The SOAP enevlope as W3C document
+     * @param ttl
+     *            This is the time difference in seconds between the
+     *            <code>Created</code> and the <code>Expires</code> in
+     *            <code>Timestamp</code>, set to zero if <code>Expires</code>
+     *            should not be added.
+     * @return Document with Timestamp added
+     * @throws Exception
+     * @deprecated replaced by
+     *             {@link WSSecTimestamp#build(Document, WSSecHeader)} and
+     *             {@link WSSecTimestamp#setTimeToLive()}
+     */
+    public Document build(Document doc, int ttl) {
+        log.debug("Begin add timestamp...");
+        Element securityHeader = insertSecurityHeader(doc);
+        ts = new Timestamp(wssConfig.isPrecisionInMilliSeconds(), doc, ttl);
+        if (id != null) {
+            ts.setID(id);
+        }
+        WSSecurityUtil.prependChildElement(doc, securityHeader,
+                ts.getElement(), true);
+        return doc;
+    }
+
+    /**
+     * Set the wsu:Id value of the Timestamp
+     * 
+     * @param id
+     * @deprecated no replacement, id is created by default in
+     *             {@link WSSecTimestamp}
+     */
+    public void setId(String id) {
+        this.id = id;
+        if (ts != null)
+            ts.setID(id);
+    }
+
+    /**
+     * Get the wsu:Id value of the Timestamp
+     * 
+     * @return TODO
+     *
+     * @deprecated replaced by {@link WSSecTimestamp#getId()}
+     */
+    public String getId() {
+        return id;
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSBaseMessage.java b/src/org/apache/ws/security/message/WSBaseMessage.java
new file mode 100644
index 0000000..268ba28
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSBaseMessage.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.Vector;
+
+/**
+ * This is the base class for WS Security messages. It provides common functions
+ * and fields used by the specific message classes such as sign, encrypt, and
+ * username token.
+ * 
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de)
+ */
+public class WSBaseMessage {
+    private static Log log = LogFactory.getLog(WSBaseMessage.class.getName());
+
+    protected String actor = null;
+
+    protected boolean mustunderstand = true;
+
+    protected String user = null;
+
+    protected String password = null;
+
+    protected int keyIdentifierType = WSConstants.ISSUER_SERIAL;
+
+    protected Vector parts = null;
+
+    protected int timeToLive = 300; // time between Created and Expires
+
+    protected boolean doDebug = false;
+
+    protected WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+
+    /**
+     * Constructor.
+     * 
+     * @deprecated replaced by {@link WSSecBase#WSSecBase()}
+     */
+    public WSBaseMessage() {
+    }
+
+    /**
+     * Constructor. <p/>
+     * 
+     * @param actor
+     *            The actor name of the <code>wsse:Security</code> header
+     * @deprecated replaced by {@link WSSecBase#WSSecBase()} and
+     *             {@link WSSecHeader} for actor specification.
+     */
+    public WSBaseMessage(String actor) {
+        this(actor, true);
+    }
+
+    /**
+     * Constructor. <p/>
+     * 
+     * @param actor
+     *            The actor name of the <code>wsse:Security</code> header
+     * @param mu
+     *            Set <code>mustUnderstand</code> to true or false
+     * 
+     * @deprecated replaced by {@link WSSecBase#WSSecBase()} and
+     *             {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSBaseMessage(String actor, boolean mu) {
+        setActor(actor);
+        setMustUnderstand(mu);
+    }
+
+    /**
+     * set actor name. <p/>
+     * 
+     * @param act
+     *            The actor name of the <code>wsse:Security</code> header
+     * @deprecated replaced by {@link WSSecHeader#setActor(String)}
+     */
+    public void setActor(String act) {
+        actor = act;
+    }
+
+    /**
+     * Set the time to live. This is the time difference in seconds between the
+     * <code>Created</code> and the <code>Expires</code> in
+     * <code>Timestamp</code>. <p/>
+     * 
+     * @param ttl
+     *            The time to live in second
+     * @deprecated replaced by {@link WSSecTimestamp#setTimeToLive(int)}
+     */
+    public void setTimeToLive(int ttl) {
+        timeToLive = ttl;
+    }
+
+    /**
+     * Set which parts of the message to encrypt/sign. <p/>
+     * 
+     * @param parts
+     *            The vector containing the WSEncryptionPart objects
+     * @deprecated replaced by {@link WSSecBase#setParts(Vector)}
+     */
+    public void setParts(Vector parts) {
+        this.parts = parts;
+    }
+
+    /**
+     * Set the <code>mustUnderstand</code> flag for the
+     * <code>wsse:Security</code> header
+     * 
+     * @param mu
+     *            Set <code>mustUnderstand</code> to true or false
+     * @deprecated replaced by {@link WSSecHeader#setMustUnderstand(boolean)}
+     */
+    public void setMustUnderstand(boolean mu) {
+        mustunderstand = mu;
+    }
+
+    /**
+     * Sets which key identifier to use. <p/> Defines the key identifier type to
+     * use in the {@link WSSignEnvelope#build(Document, Crypto) signature} or
+     * the {@link WSEncryptBody#build(Document, Crypto) ecnryption} function to
+     * set up the key identification elements.
+     * 
+     * @param keyIdType
+     * @see WSConstants#ISSUER_SERIAL
+     * @see WSConstants#BST_DIRECT_REFERENCE
+     * @see WSConstants#X509_KEY_IDENTIFIER
+     * @see WSConstants#SKI_KEY_IDENTIFIER
+     * @deprecated replaced by {@link WSSecBase#setKeyIdentifierType(int)}
+     */
+    public void setKeyIdentifierType(int keyIdType) {
+        keyIdentifierType = keyIdType;
+    }
+
+    /**
+     * Gets the value of the <code>keyIdentifyerType</code>.
+     * 
+     * @return The <code>keyIdentifyerType</code>.
+     * @see WSConstants#ISSUER_SERIAL
+     * @see WSConstants#BST_DIRECT_REFERENCE
+     * @see WSConstants#X509_KEY_IDENTIFIER
+     * @see WSConstants#SKI_KEY_IDENTIFIER
+     * @deprecated replaced by {@link WSSecBase#getKeyIdentifierType()}
+     */
+    public int getKeyIdentifierType() {
+        return keyIdentifierType;
+    }
+
+    /**
+     * @param wsConfig
+     *            The wsConfig to set.
+     * @deprecated replaced by {@link WSSecBase#setWsConfig(WSSConfig)}
+     */
+    public void setWsConfig(WSSConfig wsConfig) {
+        this.wssConfig = wsConfig;
+    }
+
+    /**
+     * Looks up or adds a body id. <p/> First try to locate the
+     * <code>wsu:Id</code> in the SOAP body element. If one is found, the
+     * value of the <code>wsu:Id</code> attribute is returned. Otherwise the
+     * methode generates a new <code>wsu:Id</code> and an appropriate value.
+     * 
+     * @param doc
+     *            The SOAP envelope as <code>Document</code>
+     * @return The value of the <code>wsu:Id</code> attribute of the SOAP body
+     * @throws Exception
+     * @deprecated replaced by {@link WSSecBase#setBodyID(Document)}
+     */
+    protected String setBodyID(Document doc) throws Exception {
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement());
+        Element bodyElement = (Element) WSSecurityUtil.getDirectChild(doc
+                .getFirstChild(), soapConstants.getBodyQName().getLocalPart(),
+                soapConstants.getEnvelopeURI());
+        if (bodyElement == null) {
+            throw new Exception("SOAP Body Element node not found");
+        }
+        return setWsuId(bodyElement);
+    }
+
+    protected String setWsuId(Element bodyElement) {
+        String id = null;
+        id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id");
+
+        if ((id == null) || (id.length() == 0)) {
+            id = "id-" + Integer.toString(bodyElement.hashCode());
+            String prefix = WSSecurityUtil.setNamespace(bodyElement,
+                    WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+            bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+        }
+        return id;
+    }
+
+    /**
+     * Set the user and password info. <p/> Both information is used to get the
+     * user's private signing key.
+     * 
+     * @param user
+     *            This is the user's alias name in the keystore that identifies
+     *            the private key to sign the document
+     * @param password
+     *            The user's password to get the private signing key from the
+     *            keystore
+     * @deprecated replaced by {@link WSSecBase#setUserInfo(String, String)}
+     */
+    public void setUserInfo(String user, String password) {
+        this.user = user;
+        this.password = password;
+    }
+
+    /**
+     * Creates a security header and inserts it as child into the SOAP Envelope.
+     * <p/> Check if a WS Security header block for an actor is already
+     * available in the document. If a header block is found return it,
+     * otherwise a new wsse:Security header block is created and the attributes
+     * set
+     * 
+     * @param doc
+     *            A SOAP envelope as <code>Document</code>
+     * @return A <code>wsse:Security</code> element
+     * @deprecated replaced by
+     *             {@link WSSecHeader#insertSecurityHeader(Document)}
+     */
+    protected Element insertSecurityHeader(Document doc) {
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement());
+        // lookup a security header block that matches actor
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(doc, actor,
+                soapConstants);
+        if (securityHeader == null) { // create if nothing found
+            securityHeader = WSSecurityUtil.findWsseSecurityHeaderBlock(doc,
+                    doc.getDocumentElement(), actor, true);
+
+            String soapPrefix = WSSecurityUtil.getPrefixNS(soapConstants
+                    .getEnvelopeURI(), securityHeader);
+            if (actor != null && actor.length() > 0) {
+                // Check for SOAP 1.2 here and use "role" instead of "actor"
+                securityHeader.setAttributeNS(soapConstants.getEnvelopeURI(),
+                        soapPrefix
+                                + ":"
+                                + soapConstants.getRoleAttributeQName()
+                                        .getLocalPart(), actor);
+            }
+            if (mustunderstand) {
+                securityHeader.setAttributeNS(soapConstants.getEnvelopeURI(),
+                        soapPrefix + ":" + WSConstants.ATTR_MUST_UNDERSTAND,
+                        soapConstants.getMustunderstand());
+            }
+        }
+        return securityHeader;
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSEncryptBody.java b/src/org/apache/ws/security/message/WSEncryptBody.java
new file mode 100644
index 0000000..27404d4
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSEncryptBody.java
@@ -0,0 +1,774 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.encryption.EncryptedData;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.cert.X509Certificate;
+import java.util.Vector;
+
+/**
+ * Encrypts a SOAP body inside a SOAP envelope according to WS Specification,
+ * X509 profile, and adds the encryption data.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com).
+ */
+public class WSEncryptBody extends WSBaseMessage {
+    private static Log log = LogFactory.getLog(WSEncryptBody.class.getName());
+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");
+
+    protected String symEncAlgo = WSConstants.AES_128;
+    protected String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;
+    protected String encCanonAlgo = null;
+    protected byte[] embeddedKey = null;
+    protected String embeddedKeyName = null;
+    protected X509Certificate useThisCert = null;
+
+    /**
+     * Symmetric key used in the EncrytpedKey.
+     */
+    protected SecretKey symmetricKey = null;
+
+    /**
+     * Symmetric key that's actually used.
+     */
+    protected SecretKey encryptionKey = null;
+
+    /**
+     * Parent node to which the EncryptedKeyElement should be added.
+     */
+    protected Element parentNode = null;
+
+    /**
+     * SecurityTokenReference to be inserted into EncryptedData/keyInfo element.
+     */
+    protected SecurityTokenReference securityTokenReference = null;
+
+    /**
+     * Constructor.
+     * @deprecated replaced by {@link WSSecEncrypt#WSSecEncrypt()}
+    */
+    public WSEncryptBody() {
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor The actor name of the <code>wsse:Security</code>
+     *              header
+     * 
+     * @deprecated replaced by {@link WSSecEncrypt#WSSecEncrypt()}
+     *             and {@link WSSecHeader} for actor specification.
+     */
+    public WSEncryptBody(String actor) {
+        super(actor);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor The actor name of the <code>wsse:Security</code> header
+     * @param mu    Set <code>mustUnderstand</code> to true or false
+     * 
+     * @deprecated replaced by {@link WSSecEncrypt#WSSecEncrypt()}
+     *             and {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSEncryptBody(String actor, boolean mu) {
+        super(actor, mu);
+    }
+
+    /**
+     * Sets the key to use during embedded encryption.
+     * <p/>
+     *
+     * @param key to use during encryption. The key must fit the
+     *            selected symmetrical encryption algorithm
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setKey(byte[])}
+     */
+    public void setKey(byte[] key) {
+        this.embeddedKey = key;
+    }
+
+    /**
+     * Sets the algorithm to encode the symmetric key.
+     * <p/>
+     * Default is the <code>WSConstants.KEYTRANSPORT_RSA15</code>
+     * algorithm.
+     *
+     * @param keyEnc specifies the key encoding algorithm.
+     * @see WSConstants#KEYTRANSPORT_RSA15
+     * @see WSConstants#KEYTRANSPORT_RSAOEP
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setKeyEnc(String)}
+     */
+    public void setKeyEnc(String keyEnc) {
+        keyEncAlgo = keyEnc;
+    }
+
+    /**
+     * Set the user name to get the encryption certificate. The public
+     * key of this certificate is used, thus no password necessary.
+     * The user name is a keystore alias usually.
+     * <p/>
+     *
+     * @param user
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setUserInfo(String)}
+     */
+    public void setUserInfo(String user) {
+        this.user = user;
+    }
+
+    /**
+     * Set the key name for EMBEDDED_KEYNAME
+     *
+     * @param embeddedKeyName
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setEmbeddedKeyName(String)}
+     */
+    public void setEmbeddedKeyName(String embeddedKeyName) {
+        this.embeddedKeyName = embeddedKeyName;
+    }
+
+    /**
+     * Set the X509 Certificate to use for encryption.
+     * If this is set <b>and</b> the key identifier is set
+     * to <code>DirectReference</code> then use this certificate
+     * to get the public key for encryption.
+     *
+     * @param cert is the X509 certificate to use for encryption
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setUseThisCert(X509Certificate)}
+     */
+    public void setUseThisCert(X509Certificate cert) {
+        useThisCert = cert;
+    }
+
+    /**
+     * Set the name of the symmetric encryption algorithm to use.
+     * <p/>
+     * This encryption alogrithm is used to encrypt
+     * the data, i.e. the SOAP Body. If the algorithm
+     * is not set then Triple DES is used. Refer to
+     * WSConstants which algorithms are supported.
+     * <p/>
+     *
+     * @param algo Is the name of the encryption algorithm
+     * @see WSConstants#TRIPLE_DES
+     * @see WSConstants#AES_128
+     * @see WSConstants#AES_192
+     * @see WSConstants#AES_256
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setSymmetricEncAlgorithm(String)}
+     */
+    public void setSymmetricEncAlgorithm(String algo) {
+        symEncAlgo = algo;
+    }
+
+    /**
+     * Set the name of an optional canonicalization algorithm to use
+     * before encryption.
+     * <p/>
+     * This c14n alogrithm is used to serialize the data before
+     * encryption, i.e. the SOAP Body. If the algorithm
+     * is not set then a standard serialization is used (provided
+     * by XMLCipher, usually a XMLSerializer according to DOM 3
+     * specification).
+     * <p/>
+     *
+     * @param algo Is the name of the canonicalization algorithm
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setEncCanonicalization(String)}
+     */
+    public void setEncCanonicalization(String algo) {
+        encCanonAlgo = algo;
+    }
+
+    /**
+     * Get the name of symmetric encryption algorithm to use.
+     * <p/>
+     * The name of the encryption alogrithm to encrypt
+     * the data, i.e. the SOAP Body. Refer to
+     * WSConstants which algorithms are supported.
+     * <p/>
+     *
+     * @return the name of the currently selected symmetric encryption
+     *         algorithm
+     * @see WSConstants#TRIPLE_DES
+     * @see WSConstants#AES_128
+     * @see WSConstants#AES_192
+     * @see WSConstants#AES_256
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#getSymmetricEncAlgorithm()}
+     */
+    public String getSymmetricEncAlgorithm() {
+        return symEncAlgo;
+    }
+
+    /**
+     * Builds the SOAP envelope with encrypted Body and adds encrypted key.
+     * <p/>
+     * This function performs several steps:
+     * <p/>
+     * <ul>
+     * <li>    First step: set the encoding namespace in the SOAP:Envelope </li>
+     * <li>    Second step: generate a symmetric key (session key) for
+     * the selected symmetric encryption alogrithm, and set the cipher
+     * into encryption mode.
+     * </li>
+     * <li> Third step: get the data to encrypt.
+     * We always encrypt the complete first child element of
+     * the SOAP Body element
+     * </li>
+     * <li>    Forth step: encrypt data, and set neccessary attributes in
+     * <code>xenc:EncryptedData</code>
+     * </li>
+     * <li>    Fifth step: get the certificate that contains the public key for
+     * the    public key algorithm that will encrypt the generated symmetric
+     * (session) key. Up to now we support RSA 1-5 as public key
+     * algorithm.
+     * </li>
+     * <li>    Sixth step: setup the <code>wsse:Security</code> header block </li>
+     * </ul>
+     *
+     * @param doc    the SOAP envelope as <code>Document</code> with
+     *               plaintext Body
+     * @param crypto an instance of the Crypto API to handle keystore and
+     *               Certificates
+     * @return the SOAP envelope with encrypted Body as <code>Document
+     *         </code>
+     * @throws WSSecurityException
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#build(Document, Crypto, WSSecHeader)}
+     */
+    public Document build(Document doc, Crypto crypto) throws WSSecurityException {
+        doDebug = log.isDebugEnabled();
+
+        if (keyIdentifierType == WSConstants.EMBEDDED_KEYNAME ||
+            keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {
+            return buildEmbedded(doc, crypto);
+        }
+
+        long t0 = 0, t1 = 0, t2 = 0, t3 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+        if (doDebug) {
+            log.debug("Beginning Encryption...");
+        }
+
+        /*
+         * Second step: generate a symmetric key (session key) for
+         * this alogrithm, and set the cipher into encryption mode.
+         */
+        // This variable is made a classs attribute :: SecretKey symmetricKey = null;
+        this.encryptionKey = this.symmetricKey;
+        if (encryptionKey == null) {
+            KeyGenerator keyGen = getKeyGenerator();
+            this.encryptionKey = keyGen.generateKey();
+        }
+        Vector encDataRefs = doEncryption(doc, this.encryptionKey);
+
+        if (tlog.isDebugEnabled()) {
+            t1 = System.currentTimeMillis();
+        }
+
+        /*
+         * At this point data is encrypted with the symmetric key and can be
+         * referenced via the above Id
+         */
+
+        /*
+         * Fifth step: get the certificate that contains the public key for the
+         * public key algorithm that will encrypt
+         * the generated symmetric (session) key.
+         * Up to now we support RSA 1-5 as public key algorithm
+         */
+        X509Certificate remoteCert = null;
+        if (useThisCert != null) {
+            remoteCert = useThisCert;
+        } else {
+            X509Certificate[] certs = crypto.getCertificates(user);
+            if (certs == null || certs.length <= 0) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "invalidX509Data",
+                        new Object[]{"for Encryption"});
+            }
+            remoteCert = certs[0];
+        }
+        String certUri = "EncCertId-" + remoteCert.hashCode();
+        if (tlog.isDebugEnabled()) {
+            t2 = System.currentTimeMillis();
+        }
+        Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e);
+        }
+        byte[] encKey = this.encryptionKey.getEncoded();
+        if (doDebug) {
+            log.debug("cipher blksize: "
+                    + cipher.getBlockSize()
+                    + ", symm key length: "
+                    + encKey.length);
+        }
+        if (cipher.getBlockSize() < encKey.length) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyTransp",
+                    new Object[]{"public key algorithm too weak to encrypt symmetric key"});
+        }
+        byte[] encryptedKey = null;
+        try {
+            encryptedKey = cipher.doFinal(encKey);
+        } catch (IllegalStateException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        } catch (IllegalBlockSizeException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        } catch (BadPaddingException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);
+        }
+        Text keyText =
+                WSSecurityUtil.createBase64EncodedTextNode(doc, encryptedKey);
+
+        /*
+         * Now we need to setup the wsse:Security header block
+         * 1) get (or create) the wsse:Security header block
+         * 2) create the xenc:EncryptedKey element. This already includes
+         *    the ExcrpytionMethod element with attributes that define
+         *    the key transport encryption algorithm
+         * 3) Generate ds:KeyInfo element, this wraps the wsse:SecurityTokenReference
+         * 4) set up the SecurityTokenReference, either with KeyIdentifier or
+         *    X509IssuerSerial. The SecTokenRef defines how to get to security
+         *    token used to encrypt the session key (this security token usually
+         *    contains a public key)
+         * 5) Create the CipherValue element structure and insert the encrypted
+         *    session key
+         * 6) The last step sets up the reference list that pints to the encrypted
+         *    data that was encrypted with this encrypted session key :-)
+         */
+        Element wsseSecurity = insertSecurityHeader(doc);
+        Element xencEncryptedKey = createEnrcyptedKey(doc, keyEncAlgo);
+        if (parentNode == null) {
+            WSSecurityUtil.prependChildElement(doc,
+                    wsseSecurity,
+                    xencEncryptedKey,
+                    true);
+        } else {
+            WSSecurityUtil.prependChildElement(doc,
+                    parentNode,
+                    xencEncryptedKey,
+                    true);
+        }
+        SecurityTokenReference secToken = new SecurityTokenReference(doc);
+
+        switch (keyIdentifierType) {
+            case WSConstants.X509_KEY_IDENTIFIER:
+                secToken.setKeyIdentifier(remoteCert);
+                // build a key id class??
+                break;
+
+            case WSConstants.SKI_KEY_IDENTIFIER:
+                secToken.setKeyIdentifierSKI(remoteCert, crypto);
+                break;
+                
+            case WSConstants.THUMBPRINT_IDENTIFIER:
+                secToken.setKeyIdentifierThumb(remoteCert);
+                break;
+
+            case WSConstants.ISSUER_SERIAL:
+                XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, remoteCert);
+                X509Data x509Data = new X509Data(doc); 
+                x509Data.add(data);
+                secToken.setX509IssuerSerial(x509Data);                
+                break;
+
+            case WSConstants.BST_DIRECT_REFERENCE:
+                Reference ref = new Reference(doc);
+                ref.setURI("#" + certUri);
+                BinarySecurity bstToken = null;
+                bstToken = new X509Security(doc);
+                ((X509Security) bstToken).setX509Certificate(remoteCert);
+                bstToken.setID(certUri);
+                ref.setValueType(bstToken.getValueType());
+                secToken.setReference(ref);
+                WSSecurityUtil.prependChildElement(doc,
+                        wsseSecurity,
+                        bstToken.getElement(),
+                        false);
+                break;
+
+            default :
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "unsupportedKeyId");
+        }
+        KeyInfo keyInfo = new KeyInfo(doc);
+        keyInfo.addUnknownElement(secToken.getElement());
+        WSSecurityUtil.appendChildElement(
+                doc, xencEncryptedKey, keyInfo.getElement());
+
+        Element xencCipherValue = createCipherValue(doc, xencEncryptedKey);
+        xencCipherValue.appendChild(keyText);
+        createDataRefList(doc, xencEncryptedKey, encDataRefs);
+        log.debug("Encryption complete.");
+        if (tlog.isDebugEnabled()) {
+            t3 = System.currentTimeMillis();
+            tlog.debug("EncryptBody: symm-enc "
+                    + (t1 - t0)
+                    + " cert "
+                    + (t2 - t1)
+                    + " key-encrypt "
+                    + (t3 - t2));
+        }
+        return doc;
+    }
+
+    private Vector doEncryption(Document doc, SecretKey encryptKey)
+        throws WSSecurityException {
+        return doEncryption(doc, encryptKey, null);
+    }
+
+    private Vector doEncryption(Document doc,
+                                SecretKey encryptKey,
+                                KeyInfo keyInfo)
+            throws WSSecurityException {
+        /*
+         * First step: set the encryption encoding namespace in the SOAP:Envelope
+         */
+        Element envelope = doc.getDocumentElement();
+        envelope.setAttributeNS(WSConstants.XMLNS_NS,
+                "xmlns:" + WSConstants.ENC_PREFIX,
+                WSConstants.ENC_NS);
+
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
+
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(symEncAlgo);
+        } catch (XMLEncryptionException e3) {
+            throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);
+        }
+
+        // if no encryption parts set - use the default
+        if (parts == null) {
+            parts = new Vector();
+            WSEncryptionPart encP =
+                    new WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),
+                            soapConstants.getEnvelopeURI(),
+                            "Content");
+            parts.add(encP);
+        }
+
+        Vector encDataRefs = new Vector();
+
+        for (int part = 0; part < parts.size(); part++) {
+            WSEncryptionPart encPart = (WSEncryptionPart) parts.get(part);
+            String elemName = encPart.getName();
+            String nmSpace = encPart.getNamespace();
+            String modifier = encPart.getEncModifier();
+            /*
+             * Third step: get the data to encrypt.
+             */
+            Element body =
+                    (Element) WSSecurityUtil.findElement(envelope,
+                            elemName,
+                            nmSpace);
+            if (body == null) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "noEncElement",
+                        new Object[]{"{" + nmSpace + "}" + elemName});
+            }
+
+            boolean content = modifier.equals("Content") ? true : false;
+            String xencEncryptedDataId = "EncDataId-" + body.hashCode();
+
+            /*
+             * Forth step: encrypt data, and set neccessary attributes in
+             * xenc:EncryptedData
+             */
+            try {
+                xmlCipher.init(XMLCipher.ENCRYPT_MODE, encryptKey);
+                EncryptedData encData = xmlCipher.getEncryptedData();
+                encData.setId(xencEncryptedDataId);
+                encData.setKeyInfo(keyInfo);
+                xmlCipher.doFinal(doc, body, content);
+            } catch (Exception e2) {
+                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e2);
+            }
+            encDataRefs.add(new String("#" + xencEncryptedDataId));
+        }
+        return encDataRefs;
+    }
+
+    private Document buildEmbedded(Document doc, Crypto crypto)
+            throws WSSecurityException {
+        doDebug = log.isDebugEnabled();
+
+        long t0 = 0, t1 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+        if (doDebug) {
+            log.debug("Beginning Encryption embedded...");
+        }
+
+
+        /*
+         * Second step: generate a symmetric key from the specified
+         * key (password) for this alogrithm, and set the cipher into
+         * encryption mode.
+         */
+        this.encryptionKey = this.symmetricKey;
+        if (this.encryptionKey == null) {
+            if (embeddedKey == null) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "noKeySupplied");
+            }
+            this.encryptionKey = WSSecurityUtil.prepareSecretKey(
+                    symEncAlgo,
+                    embeddedKey);
+        }
+
+        KeyInfo keyInfo = null;
+        if (this.keyIdentifierType == WSConstants.EMBEDDED_KEYNAME) {
+            keyInfo = new KeyInfo(doc);
+            keyInfo.addKeyName(embeddedKeyName == null ? user : embeddedKeyName);
+        } else if (this.keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {
+            /* This means that we want to embed a <wsse:SecurityTokenReference>
+            * into keyInfo element.
+            * If we need this functionality, this.secRef MUST be set before
+            * calling the build(doc, crypto) method.
+            * So if secRef is null then throw an exception.
+            */
+            if (this.securityTokenReference == null) {
+                throw new WSSecurityException(
+                        WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                        "You must set keyInfo element, if the keyIdentifier " +
+                        "== EMBED_SECURITY_TOKEN_REF");
+            } else {
+                keyInfo = new KeyInfo(doc);
+                Element tmpE = securityTokenReference.getElement();
+                tmpE.setAttributeNS(WSConstants.XMLNS_NS,
+                        "xmlns:" + tmpE.getPrefix(),
+                        tmpE.getNamespaceURI());
+                keyInfo.addUnknownElement(securityTokenReference.getElement());
+            }
+        }
+
+        Vector encDataRefs = doEncryption(doc, this.encryptionKey, keyInfo);
+
+        /*
+         * At this point data is encrypted with the symmetric key and can be
+         * referenced via the above Id
+         */
+
+        /*
+         * Now we need to setup the wsse:Security header block
+         * 1) get (or create) the wsse:Security header block
+         * 2) The last step sets up the reference list that pints to the encrypted
+         *    data that was encrypted with this encrypted session key :-)
+         */
+        Element wsseSecurity = insertSecurityHeader(doc);
+
+        Element tmpE = doc.createElement("temp");
+        Element refList = createDataRefList(doc, tmpE, encDataRefs);
+        WSSecurityUtil.prependChildElement(doc, wsseSecurity, refList, true);
+
+        if (tlog.isDebugEnabled()) {
+            tlog.debug("EncryptBody embedded: symm-enc " + (t1 - t0));
+        }
+        return doc;
+    }
+
+    private KeyGenerator getKeyGenerator() throws WSSecurityException {
+		KeyGenerator keyGen = null;
+		try {
+			/*
+			 * Assume AES as default, so initialize it
+			 */
+		    keyGen = KeyGenerator.getInstance("AES");
+			if (symEncAlgo.equalsIgnoreCase(WSConstants.TRIPLE_DES)) {
+			    keyGen = KeyGenerator.getInstance("DESede");
+			} else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) {
+				keyGen.init(128);
+			} else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) {
+				keyGen.init(192);
+			} else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) {
+				keyGen.init(256);
+			} else {
+				return null;
+			}
+		} catch (NoSuchAlgorithmException e) {
+			throw new WSSecurityException(
+					WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e);
+		}
+		return keyGen;
+	}
+
+    /**
+	 * Create DOM subtree for <code>xenc:EncryptedKey</code>
+	 * 
+	 * @param doc
+	 *            the SOAP enevelope parent document
+	 * @param keyTransportAlgo
+	 *            specifies which alogrithm to use to encrypt the symmetric key
+	 * @return an <code>xenc:EncryptedKey</code> element
+	 */
+    public static Element createEnrcyptedKey(Document doc,
+                                             String keyTransportAlgo) {
+        Element encryptedKey =
+                doc.createElementNS(WSConstants.ENC_NS,
+                        WSConstants.ENC_PREFIX + ":EncryptedKey");
+
+        WSSecurityUtil.setNamespace(encryptedKey,
+                WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX);
+        Element encryptionMethod =
+                doc.createElementNS(WSConstants.ENC_NS,
+                        WSConstants.ENC_PREFIX + ":EncryptionMethod");
+        encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, encryptionMethod);
+        return encryptedKey;
+    }
+
+    public static Element createCipherValue(Document doc,
+                                            Element encryptedKey) {
+        Element cipherData =
+                doc.createElementNS(WSConstants.ENC_NS,
+                        WSConstants.ENC_PREFIX + ":CipherData");
+        Element cipherValue =
+                doc.createElementNS(WSConstants.ENC_NS,
+                        WSConstants.ENC_PREFIX + ":CipherValue");
+        cipherData.appendChild(cipherValue);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, cipherData);
+        return cipherValue;
+    }
+
+    public static Element createDataRefList(Document doc,
+                                            Element encryptedKey,
+                                            Vector encDataRefs) {
+        Element referenceList =
+                doc.createElementNS(WSConstants.ENC_NS,
+                        WSConstants.ENC_PREFIX + ":ReferenceList");
+        for (int i = 0; i < encDataRefs.size(); i++) {
+            String dataReferenceUri = (String) encDataRefs.get(i);
+            Element dataReference =
+                    doc.createElementNS(WSConstants.ENC_NS,
+                            WSConstants.ENC_PREFIX + ":DataReference");
+            dataReference.setAttributeNS(null, "URI", dataReferenceUri);
+            referenceList.appendChild(dataReference);
+        }
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, referenceList);
+        return referenceList;
+    }
+
+    /**
+     * Sets the parent node of the EncryptedKeyElement
+     *
+     * @param element
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setParentNode(Element)}
+     */
+    public void setParentNode(Element element) {
+        parentNode = element;
+    }
+
+    /**
+     * @return TODO
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#getSymmetricKey()}
+     */
+    public SecretKey getSymmetricKey() {
+        return symmetricKey;
+    }
+
+    /**
+     * Set the symmetric key to be used for encryption
+     * @param key
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setSymmetricKey(SecretKey)}
+     */
+    public void setSymmetricKey(SecretKey key) {
+        this.symmetricKey = key;
+    }
+
+    /**
+     * Get the symmetric key used for encryption. This may be the same as
+     * the symmetric key field.
+     *
+     * @return The symmetric key
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#getEncryptionKey()}
+     */
+    public SecretKey getEncryptionKey() {
+        return this.encryptionKey;
+    }
+
+    /**
+     * @return TODO
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#getSecurityTokenReference()}
+     */
+    public SecurityTokenReference getSecurityTokenReference() {
+        return securityTokenReference;
+    }
+
+    /**
+     * @param reference
+     * @deprecated replaced by
+     *             {@link WSSecEncrypt#setSecurityTokenReference(SecurityTokenReference)}
+     */
+    public void setSecurityTokenReference(SecurityTokenReference reference) {
+        securityTokenReference = reference;
+    }
+
+}
diff --git a/src/org/apache/ws/security/message/WSSAddSAMLToken.java b/src/org/apache/ws/security/message/WSSAddSAMLToken.java
new file mode 100644
index 0000000..3a694d4
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSAddSAMLToken.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a WS SAML Assertion and inserts it into the SOAP Envelope. Refer to
+ * the WS specification, SAML Token profile
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class WSSAddSAMLToken extends WSBaseMessage {
+
+    private static Log log = LogFactory.getLog(WSSAddSAMLToken.class.getName());
+
+    /**
+     * Constructor.
+     * 
+     * @deprecated replaced by {@link WSSecSAMLToken#WSSecSAMLToken()}
+     */
+    public WSSAddSAMLToken() {
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor the name of the actor of the <code>wsse:Security</code>
+     *              header
+     * @deprecated replaced by {@link WSSecSAMLToken#WSSecSAMLToken()}
+     *             and {@link WSSecHeader} for actor specification.
+     */
+    public WSSAddSAMLToken(String actor) {
+        super(actor);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor The name of the actor of the <code>wsse:Security</code>
+     *              header
+     * @param mu    Set <code>mustUnderstand</code> to true or false
+     * 
+     * @deprecated replaced by {@link WSSecSAMLToken#WSSecSAMLToken()}
+     *             and {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSSAddSAMLToken(String actor, boolean mu) {
+        super(actor, mu);
+    }
+
+    /**
+     * Adds a new <code>SAMLAssertion</code> to a soap envelope.
+     * <p/>
+     * A complete <code>SAMLAssertion</code> is added to the
+     * <code>wsse:Security</code> header.
+     *
+     * @param doc      The SOAP enevlope as W3C document
+     * @param assertion TODO
+     * @return Document with UsernameToken added
+     * @deprecated replaced by {@link WSSecSAMLToken#build(Document, SAMLAssertion, WSSecHeader)}
+     */
+    public Document build(Document doc, SAMLAssertion assertion) {
+        log.debug("Begin add SAMLAssertion token...");
+        try {
+            Element element = (Element) assertion.toDOM(doc);
+            Element securityHeader = insertSecurityHeader(doc);
+            WSSecurityUtil.prependChildElement(doc,
+                    securityHeader,
+                    element,
+                    true);
+        } catch (SAMLException ex) {
+            ex.printStackTrace();
+            throw new RuntimeException(ex.toString());
+        }
+        return doc;
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSSAddUsernameToken.java b/src/org/apache/ws/security/message/WSSAddUsernameToken.java
new file mode 100644
index 0000000..d7e9902
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSAddUsernameToken.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a WS UsernameToken and inserts it into the SOAP Envelope.
+ * Refer to the WS specification, UsernameToken profile
+ *
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com).
+ */
+
+public class WSSAddUsernameToken extends WSBaseMessage {
+    private static Log log = LogFactory.getLog(WSSAddUsernameToken.class.getName());
+    private String passwordType = WSConstants.PASSWORD_DIGEST;
+
+    private UsernameToken ut = null;
+    private String id = null;
+    
+    /**
+     * Constructor.
+     * 
+     * @deprecated replaced by {@link WSSecUsernameToken#WSSecUsernameToken()}
+     */
+    public WSSAddUsernameToken() {
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor the name of the actor of the <code>wsse:Security</code> header
+     * @deprecated replaced by {@link WSSecUsernameToken#WSSecUsernameToken()}
+     *             and {@link WSSecHeader} for actor specification.
+     */
+    public WSSAddUsernameToken(String actor) {
+        super(actor);
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param actor The name of the actor of the <code>wsse:Security</code> header
+     * @param mu    Set <code>mustUnderstand</code> to true or false
+     * @deprecated replaced by {@link WSSecUsernameToken#WSSecUsernameToken()}
+     *             and {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSSAddUsernameToken(String actor, boolean mu) {
+        super(actor, mu);
+    }
+
+    /**
+     * Defines how to construct the password element of the
+     * <code>UsernameToken</code>.
+     *
+     * @param pwType contains the password type. Only allowed values are
+     *               {@link WSConstants#PASSWORD_DIGEST} and
+     *               {@link WSConstants#PASSWORD_TEXT}.
+     * @deprecated replaced by {@link WSSecUsernameToken#setPasswordType(String)}
+     */
+    public void setPasswordType(String pwType) {
+        if (pwType == null) {
+            passwordType = WSConstants.PASSWORD_DIGEST;
+        } else if (pwType.equals(WSConstants.PASSWORD_DIGEST) || pwType.equals(WSConstants.PASSWORD_TEXT)) {
+            passwordType = pwType;
+        }
+    }
+
+    /**
+     * Creates and adds a Nonce element to the UsernameToken.
+     * @deprecated replaced by {@link WSSecUsernameToken#addNonce()}
+     */
+    public void addNonce(Document doc) {
+        ut.addNonce(doc);
+    }
+
+    /**
+     * Creates and adds a Created element to the UsernameToken.
+     * @deprecated replaced by {@link WSSecUsernameToken#addCreated()}
+     */
+    public void addCreated(Document doc) {
+        ut.addCreated(wssConfig.isPrecisionInMilliSeconds(), doc);
+    }
+
+    /**
+     * set the id
+     * @param id
+     * @deprecated no replacement, id is created by default in
+     *             {@link WSSecUsernameToken}
+     */ 
+    public void setId(String id) {
+        this.id = id;
+        if (ut != null)
+            ut.setID(id);
+    }
+
+    /**
+     * Get a secret key derived from values in UsernameToken.
+     * @return
+     * @deprecated replaced by {@link WSSecUsernameToken#getSecretKey()}
+     */
+    public byte[] getSecretKey() {
+    	return ut.getSecretKey();
+    }
+    /**
+     * get the id
+     * @return The id
+     * @deprecated replaced by {@link WSSecUsernameToken#getId()}
+     */ 
+    public String getId() {
+        return id;
+    }
+
+    public Document preSetUsernameToken(Document doc, String username, String password) {
+        ut = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc, passwordType);
+        ut.setName(username);
+        ut.setPassword(password);
+        return doc;
+    }
+    /**
+     * Adds a new <code>UsernameToken</code> to a soap envelope.
+     * <p/>
+     * A complete <code>UsernameToken</code> is constructed and added to
+     * the <code>wsse:Security</code> header.
+     *
+     * @param doc      The SOAP enevlope as W3C document
+     * @param username The username to set in the UsernameToken
+     * @param password The password of the user
+     * @return Document with UsernameToken added
+     * @deprecated replaced by
+     *             {@link WSSecUsernameToken#build(Document, WSSecHeader)} and
+     *             {@link WSSecBase#setUserInfo(String, String)}
+     */
+    public Document build(Document doc, String username, String password) { // throws Exception {
+        log.debug("Begin add username token...");
+        Element securityHeader = insertSecurityHeader(doc);
+        if (ut == null) {
+        	preSetUsernameToken(doc, username, password);
+        }
+        if (id != null)
+            ut.setID(id);
+        WSSecurityUtil.prependChildElement(doc, securityHeader, ut.getElement(), true);
+        return doc;
+    }
+
+}
+
diff --git a/src/org/apache/ws/security/message/WSSecBase.java b/src/org/apache/ws/security/message/WSSecBase.java
new file mode 100644
index 0000000..b02d7e5
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecBase.java
@@ -0,0 +1,163 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import java.util.Vector;

+

+/**

+ * This is the base class for WS Security messages. It provides common functions

+ * and fields used by the specific message classes such as sign, encrypt, and

+ * username token.

+ * 

+ * @author Werner Dittmann (Werner.Dittmann@apache.org)

+ */

+public class WSSecBase {

+	private static Log log = LogFactory.getLog(WSSecBase.class.getName());

+

+	protected String user = null;

+

+	protected String password = null;

+

+	protected int keyIdentifierType = WSConstants.ISSUER_SERIAL;

+

+	protected Vector parts = null;

+

+	protected boolean doDebug = false;

+

+	protected WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();

+

+	/**

+	 * Constructor.

+	 */

+	public WSSecBase() {

+	}

+

+	/**

+	 * Set which parts of the message to encrypt/sign. <p/>

+	 * 

+	 * @param parts

+	 *            The vector containing the WSEncryptionPart objects

+	 */

+	public void setParts(Vector parts) {

+		this.parts = parts;

+	}

+

+	/**

+	 * Sets which key identifier to use. 

+     * 

+     * <p/> 

+     * 

+     * Defines the key identifier type to

+	 * use in the {@link WSSecSignature#prepare(Document, Crypto, WSSecHeader) method} or

+	 * the {@link WSSecEncrypt#prepare(Document, Crypto) method} function to

+	 * set up the key identification elements.

+	 * 

+	 * @param keyIdType

+	 * @see WSConstants#ISSUER_SERIAL

+	 * @see WSConstants#BST_DIRECT_REFERENCE

+	 * @see WSConstants#X509_KEY_IDENTIFIER

+	 * @see WSConstants#SKI_KEY_IDENTIFIER

+	 */

+	public void setKeyIdentifierType(int keyIdType) {

+		keyIdentifierType = keyIdType;

+	}

+

+	/**

+	 * Gets the value of the <code>keyIdentifyerType</code>.

+	 * 

+	 * @return The <code>keyIdentifyerType</code>.

+	 * @see WSConstants#ISSUER_SERIAL

+	 * @see WSConstants#BST_DIRECT_REFERENCE

+	 * @see WSConstants#X509_KEY_IDENTIFIER

+	 * @see WSConstants#SKI_KEY_IDENTIFIER

+	 */

+	public int getKeyIdentifierType() {

+		return keyIdentifierType;

+	}

+

+	/**

+	 * @param wsConfig

+	 *            The wsConfig to set.

+	 */

+	public void setWsConfig(WSSConfig wsConfig) {

+		this.wssConfig = wsConfig;

+	}

+

+	/**

+	 * Looks up or adds a body id. <p/> First try to locate the

+	 * <code>wsu:Id</code> in the SOAP body element. If one is found, the

+	 * value of the <code>wsu:Id</code> attribute is returned. Otherwise the

+	 * methode generates a new <code>wsu:Id</code> and an appropriate value.

+	 * 

+	 * @param doc

+	 *            The SOAP envelope as <code>Document</code>

+	 * @return The value of the <code>wsu:Id</code> attribute of the SOAP body

+	 * @throws Exception

+	 */

+	protected String setBodyID(Document doc) throws Exception {

+		SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc

+				.getDocumentElement());

+		Element bodyElement = (Element) WSSecurityUtil.getDirectChild(doc

+				.getFirstChild(), soapConstants.getBodyQName().getLocalPart(),

+				soapConstants.getEnvelopeURI());

+		if (bodyElement == null) {

+			throw new Exception("SOAP Body Element node not found");

+		}

+		return setWsuId(bodyElement);

+	}

+

+	protected String setWsuId(Element bodyElement) {

+		String id = null;

+		id = bodyElement.getAttributeNS(WSConstants.WSU_NS, "Id");

+

+		if ((id == null) || (id.length() == 0)) {

+			id = "id-" + Integer.toString(bodyElement.hashCode());

+			String prefix = WSSecurityUtil.setNamespace(bodyElement,

+					WSConstants.WSU_NS, WSConstants.WSU_PREFIX);

+			bodyElement.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);

+		}

+		return id;

+	}

+

+	/**

+	 * Set the user and password info. 

+	 * 

+	 * Both information is used to get the user's private signing key.

+	 * 

+	 * @param user

+	 *            This is the user's alias name in the keystore that identifies

+	 *            the private key to sign the document

+	 * @param password

+	 *            The user's password to get the private signing key from the

+	 *            keystore

+	 */

+	public void setUserInfo(String user, String password) {

+		this.user = user;

+		this.password = password;

+	}

+}

diff --git a/src/org/apache/ws/security/message/WSSecDKEncrypt.java b/src/org/apache/ws/security/message/WSSecDKEncrypt.java
new file mode 100644
index 0000000..35a8b77
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecDKEncrypt.java
@@ -0,0 +1,243 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import java.util.Vector;

+

+import javax.crypto.SecretKey;

+

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.Reference;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.encryption.EncryptedData;

+import org.apache.xml.security.encryption.XMLCipher;

+import org.apache.xml.security.encryption.XMLEncryptionException;

+import org.apache.xml.security.keys.KeyInfo;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+ * Encrypts and signes parts of a message with derived keys derived from a

+ * symmetric key. This symmetric key will be included as an EncryptedKey

+ * 

+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)

+ */

+public class WSSecDKEncrypt extends WSSecDerivedKeyBase {

+

+    protected String symEncAlgo = WSConstants.AES_128;

+    

+    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader)

+            throws WSSecurityException {

+        

+        /*

+         * Setup the encrypted key

+         */

+        prepare(doc, crypto);

+        

+        this.envelope =  doc.getDocumentElement();

+        /*

+         * prepend elements in the right order to the security header

+         */

+        prependDKElementToHeader(secHeader);

+                

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

+        if (parts == null) {

+            parts = new Vector();

+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+                    .getBodyQName().getLocalPart(), soapConstants

+                    .getEnvelopeURI(), "Content");

+            parts.add(encP);

+        }

+        Element externRefList = encryptForExternalRef(null, parts);

+        addExternalRefElement(externRefList, secHeader);

+

+        return doc;

+    }

+

+    private Vector doEncryption(Document doc, byte[] secretKey,

+            KeyInfo keyInfo, Vector references) throws WSSecurityException {

+

+        SecretKey key = WSSecurityUtil.prepareSecretKey(this.symEncAlgo, secretKey);

+        

+        

+        XMLCipher xmlCipher = null;

+        try {

+            xmlCipher = XMLCipher.getInstance(symEncAlgo);

+        } catch (XMLEncryptionException e3) {

+            throw new WSSecurityException(

+                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);

+        }

+

+        Vector encDataRefs = new Vector();

+

+        for (int part = 0; part < references.size(); part++) {

+            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);

+

+            String idToEnc = encPart.getId();

+            

+            String elemName = encPart.getName();

+            String nmSpace = encPart.getNamespace();

+            String modifier = encPart.getEncModifier();

+            /*

+             * Third step: get the data to encrypt.

+             */

+            Element body = null;

+            if (idToEnc != null) {

+                body = WSSecurityUtil.findElementById(document

+                        .getDocumentElement(), idToEnc, WSConstants.WSU_NS);

+                if (body == null) {

+                    body = WSSecurityUtil.findElementById(document

+                            .getDocumentElement(), idToEnc, null);

+                }

+            } else {

+                body = (Element) WSSecurityUtil.findElement(envelope, elemName,

+                        nmSpace);

+            }

+            if (body == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noEncElement", new Object[] { "{" + nmSpace + "}"

+                                + elemName });

+            }

+

+            boolean content = modifier.equals("Content") ? true : false;

+            String xencEncryptedDataId = "EncDataId-" + body.hashCode();

+

+            /*

+             * Forth step: encrypt data, and set neccessary attributes in

+             * xenc:EncryptedData

+             */

+            try {

+                xmlCipher.init(XMLCipher.ENCRYPT_MODE, key);

+                EncryptedData encData = xmlCipher.getEncryptedData();

+                encData.setId(xencEncryptedDataId);

+                encData.setKeyInfo(keyInfo);

+                xmlCipher.doFinal(doc, body, content);

+            } catch (Exception e2) {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_ENC_DEC, null, null, e2);

+            }

+            encDataRefs.add(new String("#" + xencEncryptedDataId));

+        }

+        return encDataRefs;

+    }

+    

+    /**

+     * Encrypt one or more parts or elements of the message (external).

+     * 

+     * This method takes a vector of <code>WSEncryptionPart</code> object that

+     * contain information about the elements to encrypt. The method call the

+     * encryption method, takes the reference information generated during

+     * encryption and add this to the <code>xenc:Reference</code> element.

+     * This method can be called after <code>prepare()</code> and can be

+     * called multiple times to encrypt a number of parts or elements.

+     * 

+     * </p>

+     * 

+     * The method generates a <code>xenc:Reference</code> element that <i>must</i>

+     * be added to the SecurityHeader. See <code>addExternalRefElement()</code>.

+     * 

+     * </p>

+     * 

+     * If the <code>dataRef</code> parameter is <code>null</code> the method

+     * creates and initializes a new Reference element.

+     * 

+     * @param dataRef

+     *            A <code>xenc:Reference</code> element or <code>null</code>

+     * @param references

+     *            A vector containing WSEncryptionPart objects

+     * @return Returns the updated <code>xenc:Reference</code> element

+     * @throws WSSecurityException

+     */

+    public Element encryptForExternalRef(Element dataRef, Vector references)

+            throws WSSecurityException {

+

+        //Create the SecurityTokenRef to the DKT

+        KeyInfo keyInfo = new KeyInfo(document);

+        SecurityTokenReference secToken = new SecurityTokenReference(document);

+        Reference ref = new Reference(document);

+        ref.setURI("#" + dktId);

+        secToken.setReference(ref);

+

+        keyInfo.addUnknownElement(secToken.getElement());

+

+        Vector encDataRefs = doEncryption(document, derivedKeyBytes, keyInfo,

+                references);

+        Element referenceList = dataRef;

+        if (referenceList == null) {

+            referenceList = document.createElementNS(WSConstants.ENC_NS,

+                    WSConstants.ENC_PREFIX + ":ReferenceList");

+        }

+        createDataRefList(document, referenceList, encDataRefs);

+        return referenceList;

+    }

+    

+    /**

+     * Adds (prepends) the external Reference element to the Security header.

+     * 

+     * The reference element <i>must</i> be created by the

+     * <code>encryptForExternalRef() </code> method. The method adds the

+     * reference element in the SecurityHeader.

+     * 

+     * @param dataRef

+     *            The external <code>enc:Reference</code> element

+     * @param secHeader

+     *            The security header.

+     */

+    public void addExternalRefElement(Element referenceList, WSSecHeader secHeader) {

+        Node node = dkt.getElement().getNextSibling();

+        if(node == null || (node != null && !(node instanceof Element))) {

+            //If (at this moment) DerivedKeyToken is the LAST element of 

+            //the security header 

+            secHeader.getSecurityHeader().appendChild(referenceList);

+        } else {

+            secHeader.getSecurityHeader().insertBefore(referenceList, node);

+        }

+        

+    }

+

+    public static Element createDataRefList(Document doc,

+            Element referenceList, Vector encDataRefs) {

+        for (int i = 0; i < encDataRefs.size(); i++) {

+            String dataReferenceUri = (String) encDataRefs.get(i);

+            Element dataReference = doc.createElementNS(WSConstants.ENC_NS,

+                    WSConstants.ENC_PREFIX + ":DataReference");

+            dataReference.setAttributeNS(null, "URI", dataReferenceUri);

+            referenceList.appendChild(dataReference);

+        }

+        return referenceList;

+    }

+

+    

+    public void setSymmetricEncAlgorithm(String algo) {

+        symEncAlgo = algo;

+    }

+

+    /**

+     * @see org.apache.ws.security.message.WSSecDerivedKeyBase#getDerivedKeyLength()

+     */

+    protected int getDerivedKeyLength() throws WSSecurityException{

+        return WSSecurityUtil.getKeyLength(this.symEncAlgo);

+    }

+    

+}

diff --git a/src/org/apache/ws/security/message/WSSecDKSign.java b/src/org/apache/ws/security/message/WSSecDKSign.java
new file mode 100644
index 0000000..9324cd9
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecDKSign.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.TransformationException;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.transforms.params.InclusiveNamespaces;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Builder to sign with derived keys
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public class WSSecDKSign extends WSSecDerivedKeyBase {
+
+    private static Log log = LogFactory.getLog(WSSecDKSign.class.getName());
+
+    protected String sigAlgo = XMLSignature.ALGO_ID_MAC_HMAC_SHA1;
+
+    protected String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+    protected byte[] signatureValue = null;
+    
+    private XMLSignature sig = null;
+    
+    private KeyInfo keyInfo = null;
+
+    private String keyInfoUri = null;
+
+    private SecurityTokenReference secRef = null;
+
+    private String strUri = null;
+    
+    private WSDocInfo wsDocInfo;
+
+    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader) throws WSSecurityException  {
+        
+        this.prepare(doc, crypto, secHeader);
+        
+
+        
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement());
+
+        if (parts == null) {
+            parts = new Vector();
+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants
+                    .getBodyQName().getLocalPart(), soapConstants
+                    .getEnvelopeURI(), "Content");
+            parts.add(encP);
+        }
+        
+        addReferencesToSign(parts, secHeader);
+        
+        this.computeSignature();
+        
+        this.prependSigToHeader(secHeader);
+        /*
+         * prepend elements in the right order to the security header
+         */
+        this.prependDKElementToHeader(secHeader);
+
+        return doc;
+    }
+    
+    protected void prepare(Document doc, Crypto crypto, WSSecHeader secHeader)
+                            throws WSSecurityException {
+        super.prepare(doc, crypto);
+        
+        wsDocInfo = new WSDocInfo(doc.hashCode());
+        wsDocInfo.setCrypto(crypto);
+        
+        /*
+         * Get an initialize a XMLSignature element.
+         */
+        if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
+            Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
+                    Constants._TAG_CANONICALIZATIONMETHOD);
+
+            canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);
+
+            if (wssConfig.isWsiBSPCompliant()) {
+                Set prefixes = getInclusivePrefixes(secHeader
+                        .getSecurityHeader(), false);
+
+                InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(
+                        doc, prefixes);
+
+                canonElem.appendChild(inclusiveNamespaces.getElement());
+            }
+
+            try {
+                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(
+                        doc, sigAlgo);
+                sig = new XMLSignature(doc, null, signatureAlgorithm
+                        .getElement(), canonElem);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        } else {
+            try {
+                sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        }
+        
+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());
+        String sigUri = "Signature-" + sig.hashCode();
+        sig.setId(sigUri);
+        
+        keyInfo = sig.getKeyInfo();
+        keyInfoUri = "KeyId-" + keyInfo.hashCode();
+        keyInfo.setId(keyInfoUri);
+        
+        secRef = new SecurityTokenReference(doc);
+        strUri = "STRId-" + secRef.hashCode();
+        secRef.setID(strUri);
+        
+        Reference refUt = new Reference(document);
+        refUt.setURI("#" + this.dktId);
+        secRef.setReference(refUt);
+        
+        keyInfo.addUnknownElement(secRef.getElement());
+    }
+    
+    
+    protected Set getInclusivePrefixes(Element target) {
+        return getInclusivePrefixes(target, true);
+    }
+
+    protected Set getInclusivePrefixes(Element target, boolean excludeVisible) {
+        Set result = new HashSet();
+        Node parent = target;
+        NamedNodeMap attributes;
+        Node attribute;
+        while (!(parent.getParentNode() instanceof Document)) {
+            parent = parent.getParentNode();
+            attributes = parent.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.add("#default");
+                    } else {
+                        result.add(attribute.getLocalName());
+                    }
+                }
+            }
+        }
+
+        if (excludeVisible == true) {
+            attributes = target.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.remove("#default");
+                    } else {
+                        result.remove(attribute.getLocalName());
+                    }
+                }
+                if (attribute.getPrefix() != null) {
+                    result.remove(attribute.getPrefix());
+                }
+            }
+
+            if (target.getPrefix() == null) {
+                result.remove("#default");
+            } else {
+                result.remove(target.getPrefix());
+            }
+        }
+
+        return result;
+    }
+    
+    /**
+     * This method adds references to the Signature.
+     * 
+     * The added references are signed when calling
+     * <code>computeSignature()</code>. This method can be called several
+     * times to add references as required. <code>addReferencesToSign()</code>
+     * can be called anytime after <code>prepare</code>.
+     * 
+     * @param references
+     *            A vector containing <code>WSEncryptionPart</code> objects
+     *            that define the parts to sign.
+     * @param secHeader
+     *            Used to compute namespaces to be inserted by
+     *            InclusiveNamespaces to be WSI compliant.
+     * @throws WSSecurityException
+     */
+    public void addReferencesToSign(Vector references, WSSecHeader secHeader)
+            throws WSSecurityException {
+        Transforms transforms = null;
+
+        Element envel = document.getDocumentElement();
+
+        for (int part = 0; part < references.size(); part++) {
+            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);
+
+            String idToSign = encPart.getId();
+
+            String elemName = encPart.getName();
+            String nmSpace = encPart.getNamespace();
+
+            /*
+             * Set up the elements to sign. There are two resevered element
+             * names: "Token" and "STRTransform" "Token": Setup the Signature to
+             * either sign the information that points to the security token or
+             * the token itself. If its a direct reference sign the token,
+             * otherwise sign the KeyInfo Element. "STRTransform": Setup the
+             * ds:Reference to use STR Transform
+             * 
+             */
+            transforms = new Transforms(document);
+            try {
+                if (idToSign != null) {
+                    Element toSignById = WSSecurityUtil.findElementById(
+                            document.getDocumentElement(), idToSign,
+                            WSConstants.WSU_NS);
+                    if (toSignById == null) {
+                        toSignById = WSSecurityUtil.findElementById(document
+                                .getDocumentElement(), idToSign, null);
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(toSignById))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + idToSign, transforms);
+                } else if (elemName.equals("Token")) {
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(keyInfo
+                                                .getElement()))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + keyInfoUri, transforms);
+                } else if (elemName.equals("STRTransform")) { // STRTransform
+                    Element ctx = createSTRParameter(document);
+                    transforms.addTransform(
+                            STRTransform.implementedTransformURI, ctx);
+                    sig.addDocument("#" + strUri, transforms);
+                } else if (elemName.equals("Assertion")) { // Assertion
+
+                    String id = null;
+                    id = SAMLUtil.getAssertionId(envel, elemName, nmSpace);
+
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envel, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    String prefix = WSSecurityUtil.setNamespace(body,
+                            WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+                    body.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+                    sig.addDocument("#" + id, transforms);
+
+                } else {
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envel, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(document,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + setWsuId(body), transforms);
+                }
+            } catch (TransformationException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            } catch (XMLSignatureException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            }
+        }
+    }
+    
+    protected Element createSTRParameter(Document doc) {
+        Element transformParam = doc.createElementNS(WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX + ":TransformationParameters");
+
+        WSSecurityUtil.setNamespace(transformParam, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        Element canonElem = doc.createElementNS(WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX + ":CanonicalizationMethod");
+
+        WSSecurityUtil.setNamespace(canonElem, WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX);
+
+        canonElem.setAttributeNS(null, "Algorithm",
+                Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+        transformParam.appendChild(canonElem);
+        return transformParam;
+    }
+    
+    
+    /**
+     * Prepends the Signature element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>.
+     * This allows to insert the Signature element at any position in the
+     * Security header.
+     * 
+     * @param securityHeader
+     *            The secHeader that holds the Signature element.
+     */
+    public void prependSigToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader.getSecurityHeader(), sig
+                .getElement(), false);
+    }
+    
+    
+    /**
+     * Compute the Signature over the references.
+     * 
+     * After references are set this method computes the Signature for them.
+     * This method can be called anytime after the references were set. See
+     * <code>addReferencesToSign()</code>.
+     * 
+     * @throws WSSecurityException
+     */
+    public void computeSignature() throws WSSecurityException {
+        WSDocInfoStore.store(wsDocInfo);
+        try {
+            sig.sign(sig.createSecretKey(derivedKeyBytes));
+            signatureValue = sig.getSignatureValue();
+        } catch (XMLSignatureException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } catch (Exception e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } finally {
+            WSDocInfoStore.delete(wsDocInfo);
+        }
+
+    }
+    
+    /**
+     * @see org.apache.ws.security.message.WSSecDerivedKeyBase#getDerivedKeyLength()
+     */
+    protected int getDerivedKeyLength() throws WSSecurityException {
+        return WSSecurityUtil.getKeyLength(this.sigAlgo);
+    }
+    
+    
+    public void setSignatureAlgorithm(String algo) {
+        this.sigAlgo = algo;
+    }
+    
+
+}
diff --git a/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java b/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java
new file mode 100644
index 0000000..d96d8b2
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecDerivedKeyBase.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.dkalgo.AlgoFactory;
+import org.apache.ws.security.conversation.dkalgo.DerivationAlgorithm;
+import org.apache.ws.security.message.token.DerivedKeyToken;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Base class for DerivedKey encryption and signature
+ *
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public abstract class WSSecDerivedKeyBase extends WSSecBase {
+    
+    protected Document document;
+    
+    /**
+     * Session key used as the secret in key derivation
+     */
+    protected byte[] ephemeralKey;
+     
+    /**
+     * DerivedKeyToken of this builder
+     */
+    protected DerivedKeyToken dkt = null;
+    
+    /**
+     * Raw bytes of the derived key
+     */
+    protected byte[] derivedKeyBytes = null; 
+    
+    /**
+     * wsu:Id of the wsc:DerivedKeyToken
+     */
+    protected String dktId = null;
+    
+
+    
+    /**
+     * soap:Envelope element
+     */
+    protected Element envelope = null;
+    
+    /**
+     * The Token identifier of the token that the <code>DerivedKeyToken</code> 
+     * is (or to be) derived from.
+     */
+    protected String tokenIdentifier = null;
+    
+    /**
+     * The derived key will change depending on the sig/encr algorithm.
+     * Therefore the child classes are expected to provide this value.
+     * @return
+     * @throws WSSecurityException
+     */
+    protected abstract int getDerivedKeyLength() throws WSSecurityException;
+   
+    /**
+     * The wsse:SecurityTokenReference element to be used
+     */
+    protected Element strElem;
+    
+    /**
+     * @param ephemeralKey The ephemeralKey to set.
+     */
+    public void setExternalKey(byte[] ephemeralKey, 
+                                String tokenIdentifier) {
+        this.ephemeralKey = ephemeralKey;
+        this.tokenIdentifier = tokenIdentifier;
+    }
+    
+    /**
+     * @param ephemeralKey The ephemeralKey to set.
+     */
+    public void setExternalKey(byte[] ephemeralKey, 
+                                Element strElem) {
+        this.ephemeralKey = ephemeralKey;
+        this.strElem = strElem;
+    }
+    
+    /**
+     * @return Returns the tokenIdentifier.
+     */
+    public String getTokenIdentifier() {
+        return tokenIdentifier;
+    }
+    
+    /**
+     * Get the id generated during <code>prepare()</code>.
+     * 
+     * Returns the the value of wsu:Id attribute of the DerivedKeyToken element.
+     * 
+     * @return Return the wsu:Id of this token or null if <code>prepare()</code>
+     *         was not called before.
+     */
+    public String getId() {
+        return dktId;
+    }
+    
+    /**
+     * Initialize a WSSec Derived key.
+     * 
+     * The method prepares and initializes a WSSec dereived key structure after the
+     * relevant information was set. This method also creates and initializes the
+     * derived token using the ephemeral key. After preparation references
+     * can be added, encrypted and signed as required.
+     * 
+     * </p>
+     * 
+     * This method does not add any element to the security header. This must be
+     * done explicitly.
+     * 
+     * @param doc
+     *            The unsigned SOAP envelope as <code>Document</code>
+     * @param crypto
+     *            An instance of the Crypto API to handle keystore and
+     *            certificates
+     * @throws WSSecurityException
+     */
+    public void prepare(Document doc, Crypto crypto)
+        throws WSSecurityException {
+        
+        document = doc;
+
+        //Create the derived keys
+        //At this point figure out the key length accordng to teh symencAlgo
+        int offset = 0;
+        int length = this.getDerivedKeyLength();
+        byte[] label;
+        try {
+            label = ConversationConstants.DEFAULT_LABEL.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new WSSecurityException("UTF-8 encoding is not supported", e);
+        }
+        byte[] nonce = WSSecurityUtil.generateNonce(16);
+        
+        byte[] seed = new byte[label.length + nonce.length];
+        System.arraycopy(label, 0, seed, 0, label.length);
+        System.arraycopy(nonce, 0, seed, label.length, nonce.length);
+        
+        DerivationAlgorithm algo = AlgoFactory.getInstance(ConversationConstants.DerivationAlgorithm.P_SHA_1);
+        
+        this.derivedKeyBytes = algo.createKey(this.ephemeralKey, seed, offset, length);
+        
+        
+        //Add the DKTs
+        dkt = new DerivedKeyToken(document);
+        dktId = "derivedKeyId-" + dkt.hashCode();
+        
+        dkt.setLength(length);
+        dkt.setNonce(Base64.encode(nonce));
+        dkt.setOffset(offset);
+        dkt.setID(dktId);
+        
+        if(this.strElem == null) {
+            //Create the SecurityTokenRef to the Encrypted Key
+            SecurityTokenReference strEncKey = new SecurityTokenReference(document);
+            Reference ref = new Reference(document);
+            ref.setURI("#" + this.tokenIdentifier);
+            strEncKey.setReference(ref);
+            dkt.setSecuityTokenReference(strEncKey); 
+        } else {
+            dkt.setSecuityTokenReference(this.strElem);
+        }
+    }
+
+
+
+    /**
+     * Prepend the DerivedKey element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the DereivedKey element at any position in the Security
+     * header.
+     * 
+     * @param secHeader
+     *            The security header that holds the Signature element.
+     */
+    public void prependDKElementToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader
+            .getSecurityHeader(), dkt.getElement(), false);
+    }
+
+}
diff --git a/src/org/apache/ws/security/message/WSSecEncrypt.java b/src/org/apache/ws/security/message/WSSecEncrypt.java
new file mode 100644
index 0000000..5e6eb9f
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecEncrypt.java
@@ -0,0 +1,626 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.Reference;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.encryption.EncryptedData;

+import org.apache.xml.security.encryption.XMLCipher;

+import org.apache.xml.security.encryption.XMLEncryptionException;

+import org.apache.xml.security.keys.KeyInfo;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import javax.crypto.KeyGenerator;

+import javax.crypto.SecretKey;

+import java.security.NoSuchAlgorithmException;

+import java.security.cert.X509Certificate;

+import java.util.Vector;

+

+/**

+ * Encrypts a parts of a message according to WS Specification, X509 profile,

+ * and adds the encryption data.

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com).

+ * @author Werner Dittmann (Werner.Dittmann@apache.org).

+ */

+public class WSSecEncrypt extends WSSecEncryptedKey {

+    private static Log log = LogFactory.getLog(WSSecEncrypt.class.getName());

+

+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");

+

+    protected String symEncAlgo = WSConstants.AES_128;

+

+    protected String encCanonAlgo = null;

+

+    protected byte[] embeddedKey = null;

+

+    protected String embeddedKeyName = null;

+

+    /**

+     * Symmetric key used in the EncrytpedKey.

+     */

+    protected SecretKey symmetricKey = null;

+

+    /**

+     * SecurityTokenReference to be inserted into EncryptedData/keyInfo element.

+     */

+    protected SecurityTokenReference securityTokenReference = null;

+

+    /**

+     * Constructor.

+     */

+    public WSSecEncrypt() {

+    }

+

+    /**

+     * Sets the key to use during embedded encryption.

+     * 

+     * <p/>

+     * 

+     * @param key

+     *            to use during encryption. The key must fit the selected

+     *            symmetrical encryption algorithm

+     */

+    public void setKey(byte[] key) {

+        this.embeddedKey = key;

+    }

+

+    /**

+     * Sets the algorithm to encode the symmetric key.

+     * 

+     * Default is the <code>WSConstants.KEYTRANSPORT_RSA15</code> algorithm.

+     * 

+     * @param keyEnc

+     *            specifies the key encoding algorithm.

+     * @see WSConstants#KEYTRANSPORT_RSA15

+     * @see WSConstants#KEYTRANSPORT_RSAOEP

+     */

+    public void setKeyEnc(String keyEnc) {

+        keyEncAlgo = keyEnc;

+    }

+

+    /**

+     * Set the key name for EMBEDDED_KEYNAME

+     * 

+     * @param embeddedKeyName

+     */

+    public void setEmbeddedKeyName(String embeddedKeyName) {

+        this.embeddedKeyName = embeddedKeyName;

+    }

+

+    /**

+     * Set the name of the symmetric encryption algorithm to use.

+     * 

+     * This encryption alogrithm is used to encrypt the data. If the algorithm

+     * is not set then AES128 is used. Refer to WSConstants which algorithms are

+     * supported.

+     * 

+     * @param algo

+     *            Is the name of the encryption algorithm

+     * @see WSConstants#TRIPLE_DES

+     * @see WSConstants#AES_128

+     * @see WSConstants#AES_192

+     * @see WSConstants#AES_256

+     */

+    public void setSymmetricEncAlgorithm(String algo) {

+        symEncAlgo = algo;

+    }

+

+    /**

+     * Set the name of an optional canonicalization algorithm to use before

+     * encryption.

+     * 

+     * This c14n alogrithm is used to serialize the data before encryption. If

+     * the algorithm is not set then a standard serialization is used (provided

+     * by XMLCipher, usually a XMLSerializer according to DOM 3 specification).

+     * 

+     * @param algo

+     *            Is the name of the canonicalization algorithm

+     */

+    public void setEncCanonicalization(String algo) {

+        encCanonAlgo = algo;

+    }

+

+    /**

+     * Get the name of symmetric encryption algorithm to use.

+     * 

+     * The name of the encryption alogrithm to encrypt the data, i.e. the SOAP

+     * Body. Refer to WSConstants which algorithms are supported.

+     * 

+     * @return the name of the currently selected symmetric encryption algorithm

+     * @see WSConstants#TRIPLE_DES

+     * @see WSConstants#AES_128

+     * @see WSConstants#AES_192

+     * @see WSConstants#AES_256

+     */

+    public String getSymmetricEncAlgorithm() {

+        return symEncAlgo;

+    }

+

+    /**

+     * Initialize a WSSec Encrypt.

+     * 

+     * The method prepares and initializes a WSSec Encrypt structure after the

+     * relevant information was set. After preparartion of the token references

+     * can be added and encrypted.

+     * 

+     * </p>

+     * 

+     * This method does not add any element to the security header. This must be

+     * done explicitly.

+     * 

+     * @param doc

+     *            The SOAP envelope as <code>Document</code>

+     * @param crypto

+     *            An instance of the Crypto API to handle keystore and

+     *            certificates

+     * @throws WSSecurityException

+     */

+    public void prepare(Document doc, Crypto crypto) throws WSSecurityException {

+

+        document = doc;

+

+        /*

+         * If no external key (symmetricalKey) was set generate an encryption

+         * key (session key) for this Encrypt element. This key will be

+         * encrypted using the public key of the receiver

+         */

+

+        if (symmetricKey == null) {

+            KeyGenerator keyGen = getKeyGenerator();

+            this.symmetricKey = keyGen.generateKey();

+        }

+        byte[] encKey = this.symmetricKey.getEncoded();

+

+        /*

+         * Get the certificate that contains the public key for the public key

+         * algorithm that will encrypt the generated symmetric (session) key.

+         */

+        X509Certificate remoteCert = null;

+        if (useThisCert != null) {

+            remoteCert = useThisCert;

+        } else {

+            X509Certificate[] certs = crypto.getCertificates(user);

+            if (certs == null || certs.length <= 0) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "invalidX509Data", new Object[] { "for Encryption" });

+            }

+            remoteCert = certs[0];

+        }

+        prepareInternal(encKey, remoteCert, crypto);

+    }

+

+    /**

+     * Builds the SOAP envelope with encrypted Body and adds encrypted key.

+     * 

+     * This is a convenience method and for backward compatibility. The method

+     * calls the single function methods in order to perform a <i>one shot

+     * encryption</i>. This method is compatible with the build method of the

+     * previous version with the exception of the additional WSSecHeader

+     * parameter.

+     * 

+     * @param doc

+     *            the SOAP envelope as <code>Document</code> with plaintext

+     *            Body

+     * @param crypto

+     *            an instance of the Crypto API to handle keystore and

+     *            Certificates

+     * @param secHeader

+     *            the security header element to hold the encrypted key element.

+     * @return the SOAP envelope with encrypted Body as <code>Document

+     *         </code>

+     * @throws WSSecurityException

+     */

+    public Document build(Document doc, Crypto crypto, WSSecHeader secHeader)

+            throws WSSecurityException {

+        doDebug = log.isDebugEnabled();

+

+        if (keyIdentifierType == WSConstants.EMBEDDED_KEYNAME

+                || keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {

+            return buildEmbedded(doc, crypto, secHeader);

+        }

+

+        if (doDebug) {

+            log.debug("Beginning Encryption...");

+        }

+

+        prepare(doc, crypto);

+

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

+        if (parts == null) {

+            parts = new Vector();

+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+                    .getBodyQName().getLocalPart(), soapConstants

+                    .getEnvelopeURI(), "Content");

+            parts.add(encP);

+        }

+

+        Element refs = encryptForInternalRef(null, parts);

+        addInternalRefElement(refs);

+

+        prependToHeader(secHeader);

+

+        if (bstToken != null) {

+            prependBSTElementToHeader(secHeader);

+        }

+

+        log.debug("Encryption complete.");

+        return doc;

+    }

+

+    /**

+     * Encrypt one or more parts or elements of the message (internal).

+     * 

+     * This method takes a vector of <code>WSEncryptionPart</code> object that

+     * contain information about the elements to encrypt. The method call the

+     * encryption method, takes the reference information generated during

+     * encryption and add this to the <code>xenc:Reference</code> element.

+     * This method can be called after <code>prepare()</code> and can be

+     * called multiple times to encrypt a number of parts or elements.

+     * 

+     * </p>

+     * 

+     * The method generates a <code>xenc:Reference</code> element that <i>must</i>

+     * be added to this token. See <code>addInternalRefElement()</code>.

+     * 

+     * </p>

+     * 

+     * If the <code>dataRef</code> parameter is <code>null</code> the method

+     * creates and initializes a new Reference element.

+     * 

+     * @param dataRef

+     *            A <code>xenc:Reference</code> element or <code>null</code>

+     * @param references

+     *            A vector containing WSEncryptionPart objects

+     * @return Returns the updated <code>xenc:Reference</code> element

+     * @throws WSSecurityException

+     */

+    public Element encryptForInternalRef(Element dataRef, Vector references)

+            throws WSSecurityException {

+        Vector encDataRefs = doEncryption(document, this.symmetricKey,

+                references);

+        Element referenceList = dataRef;

+        if (referenceList == null) {

+            referenceList = document.createElementNS(WSConstants.ENC_NS,

+                    WSConstants.ENC_PREFIX + ":ReferenceList");

+        }

+        createDataRefList(document, referenceList, encDataRefs);

+        return referenceList;

+    }

+

+    /**

+     * Encrypt one or more parts or elements of the message (external).

+     * 

+     * This method takes a vector of <code>WSEncryptionPart</code> object that

+     * contain information about the elements to encrypt. The method call the

+     * encryption method, takes the reference information generated during

+     * encryption and add this to the <code>xenc:Reference</code> element.

+     * This method can be called after <code>prepare()</code> and can be

+     * called multiple times to encrypt a number of parts or elements.

+     * 

+     * </p>

+     * 

+     * The method generates a <code>xenc:Reference</code> element that <i>must</i>

+     * be added to the SecurityHeader. See <code>addExternalRefElement()</code>.

+     * 

+     * </p>

+     * 

+     * If the <code>dataRef</code> parameter is <code>null</code> the method

+     * creates and initializes a new Reference element.

+     * 

+     * @param dataRef

+     *            A <code>xenc:Reference</code> element or <code>null</code>

+     * @param references

+     *            A vector containing WSEncryptionPart objects

+     * @return Returns the updated <code>xenc:Reference</code> element

+     * @throws WSSecurityException

+     */

+    public Element encryptForExternalRef(Element dataRef, Vector references)

+            throws WSSecurityException {

+

+        KeyInfo keyInfo = new KeyInfo(document);

+        SecurityTokenReference secToken = new SecurityTokenReference(document);

+        Reference ref = new Reference(document);

+        ref.setURI("#" + encKeyId);

+        secToken.setReference(ref);

+

+        keyInfo.addUnknownElement(secToken.getElement());

+

+        Vector encDataRefs = doEncryption(document, this.symmetricKey,

+                keyInfo, references);

+        Element referenceList = dataRef;

+        if (referenceList == null) {

+            referenceList = document.createElementNS(WSConstants.ENC_NS,

+                    WSConstants.ENC_PREFIX + ":ReferenceList");

+        }

+        createDataRefList(document, referenceList, encDataRefs);

+        return referenceList;

+    }

+

+    /**

+     * Adds the internal Reference element to this Encrypt data.

+     * 

+     * The refernce element <i>must</i> be created by the

+     * <code>encryptForInternalRef()</code> method. The refernce element is

+     * added to the <code>EncryptedKey</code> element of this encrypt block.

+     * 

+     * @param dataRef

+     *            The internal <code>enc:Reference</code> element

+     */

+    public void addInternalRefElement(Element dataRef) {

+        WSSecurityUtil.appendChildElement(document, encryptedKeyElement, dataRef);

+    }

+

+    /**

+     * Adds (prepends) the external Reference element to the Security header.

+     * 

+     * The refernce element <i>must</i> be created by the

+     * <code>encryptForExternalRef() </code> method. The method prepends the

+     * reference element in the SecurityHeader.

+     * 

+     * @param dataRef

+     *            The external <code>enc:Reference</code> element

+     * @param secHeader

+     *            The security header.

+     */

+    public void addExternalRefElement(Element dataRef, WSSecHeader secHeader) {

+        WSSecurityUtil.prependChildElement(document, secHeader

+                .getSecurityHeader(), dataRef, false);

+    }

+

+    private Vector doEncryption(Document doc, SecretKey secretKey,

+            Vector references) throws WSSecurityException {

+        return doEncryption(doc, secretKey, null, references);

+    }

+

+    private Vector doEncryption(Document doc, SecretKey secretKey,

+            KeyInfo keyInfo, Vector references) throws WSSecurityException {

+

+        XMLCipher xmlCipher = null;

+        try {

+            xmlCipher = XMLCipher.getInstance(symEncAlgo);

+        } catch (XMLEncryptionException e3) {

+            throw new WSSecurityException(

+                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3);

+        }

+

+        Vector encDataRef = new Vector();

+

+        for (int part = 0; part < references.size(); part++) {

+            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);

+

+            String idToEnc = encPart.getId();

+

+            String elemName = encPart.getName();

+            String nmSpace = encPart.getNamespace();

+            String modifier = encPart.getEncModifier();

+            /*

+             * Third step: get the data to encrypt.

+             * 

+             */

+            Element body = null;

+            if (idToEnc != null) {

+                body = WSSecurityUtil.findElementById(document

+                        .getDocumentElement(), idToEnc, WSConstants.WSU_NS);

+                if (body == null) {

+                    body = WSSecurityUtil.findElementById(document

+                            .getDocumentElement(), idToEnc, null);

+                }

+            } else {

+                body = (Element) WSSecurityUtil.findElement(envelope, elemName,

+                        nmSpace);

+            }

+            if (body == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noEncElement", new Object[] { "{" + nmSpace + "}"

+                                + elemName });

+            }

+

+            boolean content = modifier.equals("Content") ? true : false;

+            String xencEncryptedDataId = "EncDataId-" + body.hashCode();

+

+            /*

+             * Forth step: encrypt data, and set neccessary attributes in

+             * xenc:EncryptedData

+             */

+            try {

+                xmlCipher.init(XMLCipher.ENCRYPT_MODE, secretKey);

+                EncryptedData encData = xmlCipher.getEncryptedData();

+                encData.setId(xencEncryptedDataId);

+                encData.setKeyInfo(keyInfo);

+                xmlCipher.doFinal(doc, body, content);

+            } catch (Exception e2) {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_ENC_DEC, null, null, e2);

+            }

+            encDataRef.add(new String("#" + xencEncryptedDataId));

+        }

+        return encDataRef;

+    }

+

+    private Document buildEmbedded(Document doc, Crypto crypto,

+            WSSecHeader secHeader) throws WSSecurityException {

+        doDebug = log.isDebugEnabled();

+

+        if (doDebug) {

+            log.debug("Beginning Encryption embedded...");

+        }

+        envelope = doc.getDocumentElement();

+        envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"

+                + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);

+

+        /*

+         * Second step: generate a symmetric key from the specified key

+         * (password) for this alogrithm, and set the cipher into encryption

+         * mode.

+         */

+        if (this.symmetricKey == null) {

+            if (embeddedKey == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noKeySupplied");

+            }

+            this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo,

+                    embeddedKey);

+        }

+

+        KeyInfo keyInfo = null;

+        if (this.keyIdentifierType == WSConstants.EMBEDDED_KEYNAME) {

+            keyInfo = new KeyInfo(doc);

+            keyInfo

+                    .addKeyName(embeddedKeyName == null ? user

+                            : embeddedKeyName);

+        } else if (this.keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {

+            /*

+             * This means that we want to embed a <wsse:SecurityTokenReference>

+             * into keyInfo element. If we need this functionality, this.secRef

+             * MUST be set before calling the build(doc, crypto) method. So if

+             * secRef is null then throw an exception.

+             */

+            if (this.securityTokenReference == null) {

+                throw new WSSecurityException(

+                        WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,

+                        "You must set keyInfo element, if the keyIdentifier "

+                                + "== EMBED_SECURITY_TOKEN_REF");

+            } else {

+                keyInfo = new KeyInfo(doc);

+                Element tmpE = securityTokenReference.getElement();

+                tmpE.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"

+                        + tmpE.getPrefix(), tmpE.getNamespaceURI());

+                keyInfo.addUnknownElement(securityTokenReference.getElement());

+            }

+        }

+

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

+        if (parts == null) {

+            parts = new Vector();

+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+                    .getBodyQName().getLocalPart(), soapConstants

+                    .getEnvelopeURI(), "Content");

+            parts.add(encP);

+        }

+        Vector encDataRefs = doEncryption(doc, this.symmetricKey, keyInfo,

+                parts);

+

+        /*

+         * At this point data is encrypted with the symmetric key and can be

+         * referenced via the above Id

+         */

+

+        /*

+         * Now we need to setup the wsse:Security header block 1) get (or

+         * create) the wsse:Security header block 2) The last step sets up the

+         * reference list that pints to the encrypted data

+         */

+        Element wsseSecurity = secHeader.getSecurityHeader();

+

+        Element referenceList = doc.createElementNS(WSConstants.ENC_NS,

+                WSConstants.ENC_PREFIX + ":ReferenceList");

+        referenceList = createDataRefList(doc, referenceList, encDataRefs);

+        WSSecurityUtil.prependChildElement(doc, wsseSecurity, referenceList,

+                true);

+

+        return doc;

+    }

+

+    private KeyGenerator getKeyGenerator() throws WSSecurityException {

+        KeyGenerator keyGen = null;

+        try {

+            /*

+             * Assume AES as default, so initialize it

+             */

+            keyGen = KeyGenerator.getInstance("AES");

+            if (symEncAlgo.equalsIgnoreCase(WSConstants.TRIPLE_DES)) {

+                keyGen = KeyGenerator.getInstance("DESede");

+            } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) {

+                keyGen.init(128);

+            } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) {

+                keyGen.init(192);

+            } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) {

+                keyGen.init(256);

+            } else {

+                return null;

+            }

+        } catch (NoSuchAlgorithmException e) {

+            throw new WSSecurityException(

+                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e);

+        }

+        return keyGen;

+    }

+

+    /**

+     * Create DOM subtree for <code>xenc:EncryptedKey</code>

+     * 

+     * @param doc

+     *            the SOAP enevelope parent document

+     * @param keyTransportAlgo

+     *            specifies which alogrithm to use to encrypt the symmetric key

+     * @return an <code>xenc:EncryptedKey</code> element

+     */

+

+    public static Element createDataRefList(Document doc,

+            Element referenceList, Vector encDataRefs) {

+        for (int i = 0; i < encDataRefs.size(); i++) {

+            String dataReferenceUri = (String) encDataRefs.get(i);

+            Element dataReference = doc.createElementNS(WSConstants.ENC_NS,

+                    WSConstants.ENC_PREFIX + ":DataReference");

+            dataReference.setAttributeNS(null, "URI", dataReferenceUri);

+            referenceList.appendChild(dataReference);

+        }

+        return referenceList;

+    }

+

+    /**

+     * @return The symmetric key

+     */

+    public SecretKey getSymmetricKey() {

+        return symmetricKey;

+    }

+

+    /**

+     * Set the symmetric key to be used for encryption

+     * 

+     * @param key

+     */

+    public void setSymmetricKey(SecretKey key) {

+        this.symmetricKey = key;

+    }

+

+    /**

+     * @return Return the SecurityTokenRefernce

+     */

+    public SecurityTokenReference getSecurityTokenReference() {

+        return securityTokenReference;

+    }

+

+    /**

+     * @param reference

+     */

+    public void setSecurityTokenReference(SecurityTokenReference reference) {

+        securityTokenReference = reference;

+    }

+

+}

diff --git a/src/org/apache/ws/security/message/WSSecEncryptedKey.java b/src/org/apache/ws/security/message/WSSecEncryptedKey.java
new file mode 100644
index 0000000..d14e96d
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecEncryptedKey.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+/**
+ * Builder class to build an EncryptedKey.
+ * 
+ * This is expecially useful in the case where the same
+ * <code>EncryptedKey</code> has to be used to sign and encrypt the message In
+ * such a situation this builder will add the <code>EncryptedKey</code> to the
+ * security header and we can use the information form the builder to provide to
+ * other builders to reference to the token
+ */
+public class WSSecEncryptedKey extends WSSecBase {
+
+    private static Log log = LogFactory.getLog(WSSecEncryptedKey.class
+            .getName());
+
+    protected Document document;
+
+    /**
+     * soap:Envelope element
+     */
+    protected Element envelope = null;
+
+    /**
+     * Session key used as the secret in key derivation
+     */
+    protected byte[] ephemeralKey;
+
+    /**
+     * Remote user's alias to obtain the cert to encrypt the ephemeral key
+     */
+    protected String encrUser = null;
+
+    /**
+     * Algorithm used to encrypt the ephemeral key
+     */
+    protected String keyEncAlgo = WSConstants.KEYTRANSPORT_RSA15;
+
+    /**
+     * xenc:EncryptedKey element
+     */
+    protected Element encryptedKeyElement = null;
+
+    /**
+     * The Token identifier of the token that the <code>DerivedKeyToken</code>
+     * is (or to be) derived from.
+     */
+    protected String encKeyId = null;
+
+    /**
+     * BinarySecurityToken to be included in the case where BST_DIRECT_REFERENCE
+     * is used to refer to the asymm encryption cert
+     */
+    protected BinarySecurity bstToken = null;
+    
+    protected X509Certificate useThisCert = null;
+
+    /**
+     * Set the user name to get the encryption certificate.
+     * 
+     * The public key of this certificate is used, thus no password necessary.
+     * The user name is a keystore alias usually.
+     * 
+     * @param user
+     */
+    public void setUserInfo(String user) {
+        this.user = user;
+    }
+
+    /**
+     * Get the id generated during <code>prepare()</code>.
+     * 
+     * Returns the the value of wsu:Id attribute of the EncryptedKey element.
+     * 
+     * @return Return the wsu:Id of this token or null if <code>prepare()</code>
+     *         was not called before.
+     */
+    public String getId() {
+        return encKeyId;
+    }
+
+    /**
+     * Prepare the ephemeralKey and the tokens required to be added to the
+     * security header
+     * 
+     * @param doc
+     *            The SOAP envelope as <code>Document</code>
+     * @param crypto
+     *            An instance of the Crypto API to handle keystore and
+     *            certificates
+     * @throws WSSecurityException
+     */
+    public void prepare(Document doc, Crypto crypto) throws WSSecurityException {
+
+        document = doc;
+
+        /*
+         * Set up the ephemeral key
+         */
+        if (this.ephemeralKey == null) {
+            this.ephemeralKey = generateEphemeralKey();
+        }
+
+        /*
+         * Get the certificate that contains the public key for the public key
+         * algorithm that will encrypt the generated symmetric (session) key.
+         */
+        X509Certificate remoteCert = null;
+        if (useThisCert != null) {
+            remoteCert = useThisCert;
+        } else {
+            X509Certificate[] certs = crypto.getCertificates(user);
+            if (certs == null || certs.length <= 0) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "invalidX509Data", new Object[] { "for Encryption" });
+            }
+            remoteCert = certs[0];
+        }
+        
+        prepareInternal(ephemeralKey, remoteCert, crypto);
+    }
+
+    /**
+     * Encrypt the symmetric key data and prepare the EncryptedKey element
+     * 
+     * This method does the most work for to prepare the EncryptedKey element.
+     * It is also used by the WSSecEncrypt sub-class.
+     * 
+     * @param keyBytes
+     *            The bytes that represent the symmetric key
+     * @param remoteCert
+     *            The certificate that contains the public key to encrypt the
+     *            seymmetric key data
+     * @param crypto
+     *            An instance of the Crypto API to handle keystore and
+     *            certificates
+     * @throws WSSecurityException
+     */
+    protected void prepareInternal(byte[] keyBytes, X509Certificate remoteCert,
+            Crypto crypto) throws WSSecurityException {
+        String certUri = "EncCertId-" + remoteCert.hashCode();
+        Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e);
+        }
+        if (doDebug) {
+            log.debug("cipher blksize: " + cipher.getBlockSize()
+                    + ", symm key length: " + keyBytes.length);
+        }
+        if (cipher.getBlockSize() < keyBytes.length) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyTransp",
+                    new Object[] { "public key algorithm too weak to encrypt "
+                            + "symmetric key" });
+        }
+        byte[] encryptedKey = null;
+        try {
+            encryptedKey = cipher.doFinal(keyBytes);
+        } catch (IllegalStateException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e1);
+        } catch (IllegalBlockSizeException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e1);
+        } catch (BadPaddingException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    null, null, e1);
+        }
+        Text keyText = WSSecurityUtil.createBase64EncodedTextNode(document,
+                encryptedKey);
+
+        /*
+         * Now we need to setup the EncryptedKey header block 1) create a
+         * EncryptedKey element and set a wsu:Id for it 2) Generate ds:KeyInfo
+         * element, this wraps the wsse:SecurityTokenReference 3) Create and set
+         * up the SecurityTokenReference according to the keyIdentifer parameter
+         * 4) Create the CipherValue element structure and insert the encrypted
+         * session key
+         */
+        encryptedKeyElement = createEnrcyptedKey(document, keyEncAlgo);
+        this.encKeyId = "EncKeyId-" + encryptedKeyElement.hashCode();
+        encryptedKeyElement.setAttributeNS(null, "Id", this.encKeyId);
+
+        KeyInfo keyInfo = new KeyInfo(document);
+
+        SecurityTokenReference secToken = new SecurityTokenReference(document);
+
+        switch (keyIdentifierType) {
+        case WSConstants.X509_KEY_IDENTIFIER:
+            secToken.setKeyIdentifier(remoteCert);
+            break;
+
+        case WSConstants.SKI_KEY_IDENTIFIER:
+            secToken.setKeyIdentifierSKI(remoteCert, crypto);
+            break;
+
+        case WSConstants.THUMBPRINT_IDENTIFIER:
+            secToken.setKeyIdentifierThumb(remoteCert);
+            break;
+
+        case WSConstants.ISSUER_SERIAL:
+            XMLX509IssuerSerial data = new XMLX509IssuerSerial(document,
+                    remoteCert);
+            X509Data x509Data = new X509Data(document);
+            x509Data.add(data);
+            secToken.setX509IssuerSerial(x509Data);
+            break;
+
+        case WSConstants.BST_DIRECT_REFERENCE:
+            Reference ref = new Reference(document);
+            ref.setURI("#" + certUri);
+            bstToken = new X509Security(document);
+            ((X509Security) bstToken).setX509Certificate(remoteCert);
+            bstToken.setID(certUri);
+            ref.setValueType(bstToken.getValueType());
+            secToken.setReference(ref);
+            break;
+
+        default:
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyId");
+        }
+        keyInfo.addUnknownElement(secToken.getElement());
+        WSSecurityUtil.appendChildElement(document, encryptedKeyElement,
+                keyInfo.getElement());
+
+        Element xencCipherValue = createCipherValue(document,
+                encryptedKeyElement);
+        xencCipherValue.appendChild(keyText);
+
+        envelope = document.getDocumentElement();
+        envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"
+                + WSConstants.ENC_PREFIX, WSConstants.ENC_NS);
+    }
+
+    /**
+     * Create an ephemeral key
+     * 
+     * @return
+     * @throws WSSecurityException
+     */
+    protected byte[] generateEphemeralKey() throws WSSecurityException {
+        try {
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] temp = new byte[16];
+            random.nextBytes(temp);
+            return temp;
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                    "Error in creating the ephemeral key", e);
+        }
+    }
+
+    /**
+     * Create DOM subtree for <code>xenc:EncryptedKey</code>
+     * 
+     * @param doc
+     *            the SOAP enevelope parent document
+     * @param keyTransportAlgo
+     *            specifies which alogrithm to use to encrypt the symmetric key
+     * @return an <code>xenc:EncryptedKey</code> element
+     */
+
+    protected Element createEnrcyptedKey(Document doc, String keyTransportAlgo) {
+        Element encryptedKey = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":EncryptedKey");
+
+        WSSecurityUtil.setNamespace(encryptedKey, WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX);
+        Element encryptionMethod = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":EncryptionMethod");
+        encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, encryptionMethod);
+        return encryptedKey;
+    }
+
+    protected Element createCipherValue(Document doc, Element encryptedKey) {
+        Element cipherData = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":CipherData");
+        Element cipherValue = doc.createElementNS(WSConstants.ENC_NS,
+                WSConstants.ENC_PREFIX + ":CipherValue");
+        cipherData.appendChild(cipherValue);
+        WSSecurityUtil.appendChildElement(doc, encryptedKey, cipherData);
+        return cipherValue;
+    }
+
+    /**
+     * Prepend the EncryptedKey element to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the EncryptedKey element at any position in the Security
+     * header.
+     * 
+     * @param secHeader
+     *            The security header that holds the Signature element.
+     */
+    public void prependToHeader(WSSecHeader secHeader) {
+        WSSecurityUtil.prependChildElement(document, secHeader
+                .getSecurityHeader(), encryptedKeyElement, false);
+    }
+
+    /**
+     * Prepend the BinarySecurityToken to the elements already in the Security
+     * header.
+     * 
+     * The method can be called any time after <code>prepare()</code>. This
+     * allows to insert the BST element at any position in the Security header.
+     * 
+     * @param secHeader
+     *            The security header that holds the BST element.
+     */
+    public void prependBSTElementToHeader(WSSecHeader secHeader) {
+        if (bstToken != null) {
+            WSSecurityUtil.prependChildElement(document, secHeader
+                    .getSecurityHeader(), bstToken.getElement(), false);
+        }
+        bstToken = null;
+    }
+
+    /**
+     * @return Returns the ephemeralKey.
+     */
+    public byte[] getEphemeralKey() {
+        return ephemeralKey;
+    }
+    
+    /**
+     * Set the X509 Certificate to use for encryption.
+     * 
+     * If this is set <b>and</b> the key identifier is set to
+     * <code>DirectReference</code> then use this certificate to get the
+     * public key for encryption.
+     * 
+     * @param cert
+     *            is the X509 certificate to use for encryption
+     */
+    public void setUseThisCert(X509Certificate cert) {
+        useThisCert = cert;
+    }
+
+    /**
+     * @return Returns the encryptedKeyElement.
+     */
+    public Element getEncryptedKeyElement() {
+        return encryptedKeyElement;
+    }
+    
+    /**
+     * @return Returns the BinarySecurityToken element.
+     */
+    public Element getBinarySecurityTokenElement() {
+        if(this.bstToken != null) {
+            return this.bstToken.getElement();
+        } else  {
+            return null;
+        }
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSSecHeader.java b/src/org/apache/ws/security/message/WSSecHeader.java
new file mode 100644
index 0000000..66e826d
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecHeader.java
@@ -0,0 +1,153 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+/**

+ * This class implements WS Security header.

+ * 

+ * Setup a Security header with a specified actor and mustunderstand flag.

+ * 

+ * <p/>

+ * 

+ * The defaults for actor and mustunderstand are: empty <code>actor</code> and

+ * <code>mustunderstand</code> is true.

+ * 

+ * @author Werner Dittmann (Werner.Dittmann@apache.org)

+ */

+public class WSSecHeader {

+    private static Log log = LogFactory.getLog(WSSecHeader.class.getName());

+

+    protected String actor = null;

+

+    protected boolean mustunderstand = true;

+

+    protected boolean doDebug = false;

+

+    private Element securityHeader = null;

+

+    /**

+     * Constructor.

+     */

+    public WSSecHeader() {

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param actor

+     *            The actor name of the <code>wsse:Security</code> header

+     */

+    public WSSecHeader(String actor) {

+        this(actor, true);

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param actor

+     *            The actor name of the <code>wsse:Security</code> header

+     * @param mu

+     *            Set <code>mustUnderstand</code> to true or false

+     */

+    public WSSecHeader(String act, boolean mu) {

+        actor = act;

+        mustunderstand = mu;

+    }

+

+    /**

+     * set actor name.

+     * 

+     * @param act

+     *            The actor name of the <code>wsse:Security</code> header

+     */

+    public void setActor(String act) {

+        actor = act;

+    }

+

+    /**

+     * Set the <code>mustUnderstand</code> flag for the

+     * <code>wsse:Security</code> header.

+     * 

+     * @param mu

+     *            Set <code>mustUnderstand</code> to true or false

+     */

+    public void setMustUnderstand(boolean mu) {

+        mustunderstand = mu;

+    }

+

+    /**

+     * Get the security header element of this instance.

+     * 

+     * @return The security header element.

+     */

+    public Element getSecurityHeader() {

+        return securityHeader;

+    }

+

+    /**

+     * Creates a security header and inserts it as child into the SOAP Envelope.

+     * 

+     * <p/>

+     * 

+     * Check if a WS Security header block for an actor is already available in

+     * the document. If a header block is found return it, otherwise a new

+     * wsse:Security header block is created and the attributes set

+     * 

+     * @param doc

+     *            A SOAP envelope as <code>Document</code>

+     * @return A <code>wsse:Security</code> element

+     */

+    public Element insertSecurityHeader(Document doc) {

+

+        /*

+         * If there is already a security header in this instance just return it

+         */

+        if (securityHeader != null) {

+            return securityHeader;

+        }

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc

+                .getDocumentElement());

+

+        securityHeader = WSSecurityUtil.findWsseSecurityHeaderBlock(doc, doc

+                .getDocumentElement(), actor, true);

+

+        String soapPrefix = WSSecurityUtil.getPrefixNS(soapConstants

+                .getEnvelopeURI(), securityHeader);

+        if (actor != null && actor.length() > 0) {

+            securityHeader.setAttributeNS(soapConstants.getEnvelopeURI(),

+                    soapPrefix

+                            + ":"

+                            + soapConstants.getRoleAttributeQName()

+                                    .getLocalPart(), actor);

+        }

+        if (mustunderstand) {

+            securityHeader.setAttributeNS(soapConstants.getEnvelopeURI(),

+                    soapPrefix + ":" + WSConstants.ATTR_MUST_UNDERSTAND,

+                    soapConstants.getMustunderstand());

+        }

+        return securityHeader;

+    }

+}

diff --git a/src/org/apache/ws/security/message/WSSecSAMLToken.java b/src/org/apache/ws/security/message/WSSecSAMLToken.java
new file mode 100644
index 0000000..ce7275f
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecSAMLToken.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Builds a WS SAML Assertion and inserts it into the SOAP Envelope. Refer to
+ * the WS specification, SAML Token profile
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class WSSecSAMLToken extends WSSecBase {
+
+    private static Log log = LogFactory.getLog(WSSecSAMLToken.class.getName());
+    
+    private Document document = null;
+    
+    private SAMLAssertion saml = null;
+
+    /**
+     * Constructor.
+     */
+    public WSSecSAMLToken() {
+    }
+
+    /**
+     * Creates a SAML token.
+     * 
+     * The method prepares and initializes a WSSec UsernameToken structure after
+     * the relevant information was set. A Before calling
+     * <code>prepare()</code> all parameters such as user, password,
+     * passwordType etc. must be set. A complete <code>UsernameToken</code> is
+     * constructed.
+     * 
+     * @param doc
+     *            The SOAP enevlope as W3C document
+     */
+    public void prepare(Document doc, SAMLAssertion assertion) {
+        document = doc;
+        saml = assertion;
+    }
+
+    /**
+     * Prepends the SAML Assertion to the elements already in the
+     * Security header.
+     * 
+     * The method can be called any time after <code>prepare()</code>.
+     * This allows to insert the SAML assertion at any position in the
+     * Security header.
+     * 
+     * @param secHeader
+     *            The security header that holds the Signature element.
+     */
+    public void prependToHeader(WSSecHeader secHeader) {
+        Element element = null;        
+        try {
+            element = (Element) saml.toDOM(document);
+        } catch (SAMLException ex) {
+            throw new RuntimeException(ex.toString());
+        }
+        
+        WSSecurityUtil.prependChildElement(document, secHeader
+                .getSecurityHeader(), element, false);
+    }
+    
+    /**
+     * Get the id generated during <code>prepare()</code>.
+     * 
+     * Returns the the value of wsu:Id attribute of this Timestamp. 
+     * 
+     * @return Return the wsu:Id of this token or null if <code>prepareToken()</code>
+     * was not called before.
+     */
+    public String getId() {
+        if (saml == null) {
+            return null;
+        }
+        return saml.getId();
+    }
+    
+    /**
+     * Adds a new <code>SAMLAssertion</code> to a soap envelope.
+     * <p/>
+     * A complete <code>SAMLAssertion</code> is added to the
+     * <code>wsse:Security</code> header.
+     *
+     * @param doc      The SOAP enevlope as W3C document
+     * @param assertion TODO
+     * @return Document with UsernameToken added
+     */
+    public Document build(Document doc, SAMLAssertion assertion, WSSecHeader secHeader) {
+        log.debug("Begin add SAMLAssertion token...");
+        
+        prepare(doc, assertion);
+        prependToHeader(secHeader);
+        
+        return doc;
+    }
+}
diff --git a/src/org/apache/ws/security/message/WSSecSecurityContextToken.java b/src/org/apache/ws/security/message/WSSecSecurityContextToken.java
new file mode 100644
index 0000000..c51159a
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecSecurityContextToken.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.message;
+
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.SecurityContextToken;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+
+/**
+ * Builder class to add a <code>wsc:SecurityContextToken</code> into the
+ * <code>wsse:Security</code>
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class WSSecSecurityContextToken {
+
+    /**
+     * The <code>wsc:SecurityContextToken</code> to be added to the
+     * <code>wsse:SecurityHeader</code>
+     */
+    private SecurityContextToken sct;
+
+    /**
+     * The <code>wsu:Id</code> of the <code>wsc:SecurityContextToken</code> 
+     */
+    private String sctId;
+
+    /**
+     * The <code>wsc:Identifier</code> of the
+     * <code>wsc:SecurityContextToken</code>
+     */
+    private String identifier;
+
+    /**
+     * The symmetric secret associated with the SecurityContextToken
+     */
+    protected byte[] secret;
+
+    public void prepare(Document doc, Crypto crypto)
+            throws WSSecurityException {
+
+        if (sct == null) {
+            if (this.identifier != null) {
+                this.sct = new SecurityContextToken(doc, this.identifier);
+            } else {
+                this.sct = new SecurityContextToken(doc);
+                this.identifier = this.sct.getIdentifier();
+            }
+        }
+
+        // The wsu:Id of the wsc:SecurityContextToken
+        if (this.sctId != null) {
+            this.sct.setID(this.sctId);
+        }
+    }
+
+    public void prependSCTElementToHeader(Document doc, WSSecHeader secHeader)
+            throws WSSecurityException {
+        WSSecurityUtil.prependChildElement(doc, secHeader.getSecurityHeader(),
+                sct.getElement(), false);
+    }
+
+    /**
+     * @return Returns the sct.
+     */
+    public SecurityContextToken getSct() {
+        return sct;
+    }
+
+    /**
+     * @param sct
+     *            The sct to set.
+     */
+    public void setSct(SecurityContextToken sct) {
+        this.sct = sct;
+    }
+
+    /**
+     * @return Returns the ephemeralKey.
+     */
+    public byte[] getSecret() {
+        return secret;
+    }
+
+    /**
+     * @param ephemeralKey
+     *            The ephemeralKey to set.
+     */
+    protected void setSecret(byte[] ephemeralKey) {
+        this.secret = ephemeralKey;
+    }
+
+    /**
+     * @return Returns the identifier.
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @param identifier The identifier to set.
+     */
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+    /**
+     * @return Returns the sctId.
+     */
+    public String getSctId() {
+        if(this.sct != null) {
+            return this.sct.getID();
+        } else {
+            return this.sctId;
+        }
+    }
+
+    /**
+     * @param sctId The sctId to set.
+     */
+    public void setSctId(String sctId) {
+        this.sctId = sctId;
+    }
+    
+}
diff --git a/src/org/apache/ws/security/message/WSSecSignature.java b/src/org/apache/ws/security/message/WSSecSignature.java
new file mode 100644
index 0000000..332393e
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecSignature.java
@@ -0,0 +1,745 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.PKIPathSecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.TransformationException;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.transforms.params.InclusiveNamespaces;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Creates a Signature according to WS Specification, X509 profile.
+ * 
+ * This class is a refactored implementation of the previous WSS4J class
+ * <code>WSSignEnvlope</code>. This new class allows better control of
+ * the process to create a Signature and to add it to the Security header.
+ * 
+ * <br/>
+ * 
+ * The flexibility and fine granular control is required to implement a handler
+ * that uses WSSecurityPolicy files to control the setup of a Security header.
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (werner@apache.org)
+ */
+public class WSSecSignature extends WSSecBase {
+
+	private static Log log = LogFactory.getLog(WSSecSignature.class.getName());
+
+	protected boolean useSingleCert = true;
+
+	protected String sigAlgo = null;
+
+	protected String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+	protected WSSecUsernameToken usernameToken = null;
+
+	protected byte[] signatureValue = null;
+
+	/*
+	 * The following private variable are setup during prepare().
+	 */
+	protected Document document = null;
+
+	private Crypto crypto = null;
+
+	protected WSDocInfo wsDocInfo = null;
+
+	protected String certUri = null;
+
+	protected XMLSignature sig = null;
+
+	protected KeyInfo keyInfo = null;
+
+	protected String keyInfoUri = null;
+
+	protected SecurityTokenReference secRef = null;
+
+	protected String strUri = null;
+
+	private byte[] secretKey = null;
+
+	protected BinarySecurity bstToken = null;
+
+	/**
+	 * Constructor.
+	 */
+	public WSSecSignature() {
+	}
+
+	/**
+	 * set the single cert flag.
+	 * 
+	 * @param useSingleCert
+	 */
+	public void setUseSingleCertificate(boolean useSingleCert) {
+		this.useSingleCert = useSingleCert;
+	}
+
+	/**
+	 * Get the single cert flag.
+	 * 
+	 * @return A blolean if single vertificate is set.
+	 */
+	public boolean isUseSingleCertificate() {
+		return this.useSingleCert;
+	}
+
+	/**
+	 * Set the name of the signature encryption algorithm to use.
+	 * 
+	 * If the algorithm is not set then an automatic detection of the signature
+	 * algorithm to use is perfomed during the <code>prepare()</code>
+	 * method. Refer to WSConstants which algorithms are supported.
+	 * 
+	 * @param algo
+	 *            Is the name of the signature algorithm
+	 * @see WSConstants#RSA
+	 * @see WSConstants#DSA
+	 */
+	public void setSignatureAlgorithm(String algo) {
+		sigAlgo = algo;
+	}
+
+	/**
+	 * Get the name of the signature algorithm that is being used.
+	 * 
+	 * Call this method after <code>prepare</code> to get the information
+	 * which signature algorithem was automaticall detected if no signature
+	 * algorithm was preset.
+	 * 
+	 * @return the identifier URI of the signature algorithm
+	 */
+	public String getSignatureAlgorithm() {
+		return sigAlgo;
+	}
+
+	/**
+	 * Set the canonicalization method to use.
+	 * 
+	 * If the canonicalization method is not set then the recommended Exclusive
+	 * XML Canonicalization is used by default Refer to WSConstants which
+	 * algorithms are supported.
+	 * 
+	 * @param algo
+	 *            Is the name of the signature algorithm
+	 * @see WSConstants#C14N_OMIT_COMMENTS
+	 * @see WSConstants#C14N_WITH_COMMENTS
+	 * @see WSConstants#C14N_EXCL_OMIT_COMMENTS
+	 * @see WSConstants#C14N_EXCL_WITH_COMMENTS
+	 */
+	public void setSigCanonicalization(String algo) {
+		canonAlgo = algo;
+	}
+
+	/**
+	 * Get the canonicalization method.
+	 * 
+	 * If the canonicalization method was not set then Exclusive XML
+	 * Canonicalization is used by default.
+	 * 
+	 * @return The string describing the canonicalization algorithm.
+	 */
+	public String getSigCanonicalization() {
+		return canonAlgo;
+	}
+
+	/**
+	 * @param usernameToken
+	 *            The usernameToken to set.
+	 */
+	public void setUsernameToken(WSSecUsernameToken usernameToken) {
+		this.usernameToken = usernameToken;
+	}
+
+	/**
+	 * Returns the computed Signature value.
+	 * 
+	 * Call this method after <code>computeSignature()</code> or <code>build()</code>
+	 * methods were called.
+	 * 
+	 * @return Returns the signatureValue.
+	 */
+	public byte[] getSignatureValue() {
+		return signatureValue;
+	}
+
+	/**
+	 * Get the id generated during <code>prepare()</code>.
+	 * 
+	 * Returns the the value of wsu:Id attribute of the Signature element.
+	 * 
+	 * @return Return the wsu:Id of this token or null if <code>prepare()</code>
+	 *         was not called before.
+	 */
+	public String getId() {
+		if (sig == null) {
+			return null;
+		}
+		return sig.getId();
+	}
+
+	/**
+	 * Initialize a WSSec Signature.
+	 * 
+	 * The method sets up and initializes a WSSec Signature structure after the
+	 * relevant information was set. After setup of the references to elements
+	 * to sign may be added. After all references are added they can be signed.
+	 * 
+	 * <p/>
+	 * 
+	 * This method does not add the Signature element to the security header.
+	 * See <code>prependSignatureElementToHeader()</code> method.
+	 * 
+	 * @param doc
+	 *            The SOAP envelope as <code>Document</code>
+	 * @param cr
+	 *            An instance of the Crypto API to handle keystore and
+	 *            certificates
+	 * @param secHeader
+	 *            The security header that will hold the Signature. This ise use
+	 *            to construct namespace prefixes for Signature. This method
+	 * @throws WSSecurityException
+	 */
+	public void prepare(Document doc, Crypto cr, WSSecHeader secHeader)
+			throws WSSecurityException {
+		/*
+		 * Gather some info about the document to process and store it for
+		 * retrival
+		 */
+		crypto = cr;
+		document = doc;
+
+		wsDocInfo = new WSDocInfo(doc.hashCode());
+		wsDocInfo.setCrypto(cr);
+
+		/*
+		 * At first get the security token (certificate) according to the
+		 * parameters.
+		 */
+		X509Certificate[] certs = null;
+		if (keyIdentifierType != WSConstants.UT_SIGNING) {
+			certs = crypto.getCertificates(user);
+			if (certs == null || certs.length <= 0) {
+				throw new WSSecurityException(WSSecurityException.FAILURE,
+						"invalidX509Data", new Object[] { "for Signature" });
+			}
+			certUri = "CertId-" + certs[0].hashCode();
+			/*
+			 * If no signature algo was set try to detect it accroding to the
+			 * data stored in the certificate.
+			 */
+			if (sigAlgo == null) {
+				String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
+				log.debug("automatic sig algo detection: " + pubKeyAlgo);
+				if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+					sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+				} else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
+					sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
+				} else {
+					throw new WSSecurityException(
+							WSSecurityException.FAILURE,
+							"invalidX509Data",
+							new Object[] { "for Signature - unkown public key Algo" });
+				}
+			}
+		}
+
+		/*
+		 * Get an initialized XMLSignature element.
+		 */
+		if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
+			Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
+					Constants._TAG_CANONICALIZATIONMETHOD);
+
+			canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);
+
+			if (wssConfig.isWsiBSPCompliant()) {
+				Set prefixes = getInclusivePrefixes(secHeader.getSecurityHeader(), false);
+
+				InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(
+						doc, prefixes);
+
+				canonElem.appendChild(inclusiveNamespaces.getElement());
+			}
+
+			try {
+				SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(
+						doc, sigAlgo);
+				sig = new XMLSignature(doc, null, signatureAlgorithm
+						.getElement(), canonElem);
+			} catch (XMLSecurityException e) {
+				log.error("", e);
+				throw new WSSecurityException(
+						WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+			}
+		} else {
+			try {
+				sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
+			} catch (XMLSecurityException e) {
+				log.error("", e);
+				throw new WSSecurityException(
+						WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+			}
+		}
+
+		sig.addResourceResolver(EnvelopeIdResolver.getInstance());
+		String sigUri = "Signature-" + sig.hashCode();
+		sig.setId(sigUri);
+
+		keyInfo = sig.getKeyInfo();
+		keyInfoUri = "KeyId-" + keyInfo.hashCode();
+		keyInfo.setId(keyInfoUri);
+
+		secRef = new SecurityTokenReference(doc);
+		strUri = "STRId-" + secRef.hashCode();
+		secRef.setID(strUri);
+
+		/*
+		 * Prepare and setup the token references for this Signature
+		 */
+		switch (keyIdentifierType) {
+		case WSConstants.BST_DIRECT_REFERENCE:
+			Reference ref = new Reference(document);
+			ref.setURI("#" + certUri);
+			if (!useSingleCert) {
+				bstToken = new PKIPathSecurity(document);
+				((PKIPathSecurity) bstToken).setX509Certificates(certs, false,
+						crypto);
+			} else {
+				bstToken = new X509Security(document);
+				((X509Security) bstToken).setX509Certificate(certs[0]);
+			}
+			ref.setValueType(bstToken.getValueType());
+			secRef.setReference(ref);
+			bstToken.setID(certUri);
+			wsDocInfo.setBst(bstToken.getElement());
+			break;
+
+		case WSConstants.ISSUER_SERIAL:
+			XMLX509IssuerSerial data = new XMLX509IssuerSerial(document,
+					certs[0]);
+			X509Data x509Data = new X509Data(document);
+			x509Data.add(data);
+			secRef.setX509IssuerSerial(x509Data);
+			break;
+
+		case WSConstants.X509_KEY_IDENTIFIER:
+			secRef.setKeyIdentifier(certs[0]);
+			break;
+
+		case WSConstants.SKI_KEY_IDENTIFIER:
+			secRef.setKeyIdentifierSKI(certs[0], crypto);
+			break;
+
+		case WSConstants.UT_SIGNING:
+			Reference refUt = new Reference(document);
+			refUt.setValueType(WSConstants.USERNAMETOKEN_NS + "#UsernameToken");
+			String utId = usernameToken.getId();
+			refUt.setURI("#" + utId);
+			secRef.setReference(refUt);
+			secretKey = usernameToken.getSecretKey();
+			break;
+
+		case WSConstants.THUMBPRINT_IDENTIFIER:
+			secRef.setKeyIdentifierThumb(certs[0]);
+			break;
+
+		default:
+			throw new WSSecurityException(WSSecurityException.FAILURE,
+					"unsupportedKeyId");
+		}
+		keyInfo.addUnknownElement(secRef.getElement());
+
+	}
+
+	/**
+	 * This method adds references to the Signature.
+	 * 
+	 * The added references are signed when calling
+	 * <code>computeSignature()</code>. This method can be called several
+	 * times to add references as required. <code>addReferencesToSign()</code>
+	 * can be called anytime after <code>prepare</code>.
+	 * 
+	 * @param references
+	 *            A vector containing <code>WSEncryptionPart</code> objects
+	 *            that define the parts to sign.
+	 * @param secHeader
+	 *            Used to compute namespaces to be inserted by
+	 *            InclusiveNamespaces to be WSI compliant.
+	 * @throws WSSecurityException
+	 */
+	public void addReferencesToSign(Vector references, WSSecHeader secHeader)
+			throws WSSecurityException {
+		Transforms transforms = null;
+
+		Element envelope = document.getDocumentElement();
+
+		for (int part = 0; part < references.size(); part++) {
+			WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);
+
+			String idToSign = encPart.getId();
+
+			String elemName = encPart.getName();
+			String nmSpace = encPart.getNamespace();
+
+			/*
+			 * Set up the elements to sign. There are two resevered element
+			 * names: "Token" and "STRTransform" "Token": Setup the Signature to
+			 * either sign the information that points to the security token or
+			 * the token itself. If its a direct reference sign the token,
+			 * otherwise sign the KeyInfo Element. "STRTransform": Setup the
+			 * ds:Reference to use STR Transform
+			 * 
+			 */
+			transforms = new Transforms(document);
+			try {
+				if (idToSign != null) {
+					Element toSignById = WSSecurityUtil.findElementById(
+							document.getDocumentElement(), idToSign,
+							WSConstants.WSU_NS);
+					if (toSignById == null) {
+						toSignById = WSSecurityUtil.findElementById(document
+								.getDocumentElement(), idToSign, null);
+					}
+					transforms
+							.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+					if (wssConfig.isWsiBSPCompliant()) {
+						transforms.item(0).getElement().appendChild(
+								new InclusiveNamespaces(document,
+										getInclusivePrefixes(toSignById))
+										.getElement());
+					}
+					sig.addDocument("#" + idToSign, transforms);
+				} else if (elemName.equals("Token")) {
+					transforms
+							.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+					if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {
+						if (wssConfig.isWsiBSPCompliant()) {
+							transforms
+									.item(0)
+									.getElement()
+									.appendChild(
+											new InclusiveNamespaces(
+													document,
+													getInclusivePrefixes(secHeader.getSecurityHeader()))
+													.getElement());
+						}
+						sig.addDocument("#" + certUri, transforms);
+					} else {
+						if (wssConfig.isWsiBSPCompliant()) {
+							transforms.item(0).getElement().appendChild(
+									new InclusiveNamespaces(document,
+											getInclusivePrefixes(keyInfo
+													.getElement()))
+											.getElement());
+						}
+						sig.addDocument("#" + keyInfoUri, transforms);
+					}
+				} else if (elemName.equals("STRTransform")) { // STRTransform
+					Element ctx = createSTRParameter(document);
+					transforms.addTransform(
+							STRTransform.implementedTransformURI, ctx);
+					sig.addDocument("#" + strUri, transforms);
+				} else if (elemName.equals("Assertion")) { // Assertion
+
+					String id = null;
+					id = SAMLUtil.getAssertionId(envelope, elemName, nmSpace);
+
+					Element body = (Element) WSSecurityUtil.findElement(
+							envelope, elemName, nmSpace);
+					if (body == null) {
+						throw new WSSecurityException(
+								WSSecurityException.FAILURE, "noEncElement",
+								new Object[] { nmSpace + ", " + elemName });
+					}
+					transforms
+							.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+					if (wssConfig.isWsiBSPCompliant()) {
+						transforms.item(0).getElement().appendChild(
+								new InclusiveNamespaces(document,
+										getInclusivePrefixes(body))
+										.getElement());
+					}
+					String prefix = WSSecurityUtil.setNamespace(body,
+							WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+					body.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+					sig.addDocument("#" + id, transforms);
+
+				} else {
+					Element body = (Element) WSSecurityUtil.findElement(
+							envelope, elemName, nmSpace);
+					if (body == null) {
+						throw new WSSecurityException(
+								WSSecurityException.FAILURE, "noEncElement",
+								new Object[] { nmSpace + ", " + elemName });
+					}
+					transforms
+							.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+					if (wssConfig.isWsiBSPCompliant()) {
+						transforms.item(0).getElement().appendChild(
+								new InclusiveNamespaces(document,
+										getInclusivePrefixes(body))
+										.getElement());
+					}
+					sig.addDocument("#" + setWsuId(body), transforms);
+				}
+			} catch (TransformationException e1) {
+				throw new WSSecurityException(
+						WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+						e1);
+			} catch (XMLSignatureException e1) {
+				throw new WSSecurityException(
+						WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+						e1);
+			}
+		}
+	}
+
+	/**
+	 * Prepends the Signature element to the elements already in the Security
+	 * header.
+	 * 
+	 * The method can be called any time after <code>prepare()</code>.
+	 * This allows to insert the Signature element at any position in the
+	 * Security header.
+	 * 
+	 * @param securityHeader
+	 *            The secHeader that holds the Signature element.
+	 */
+	public void prependToHeader(WSSecHeader secHeader) {
+		WSSecurityUtil.prependChildElement(document, secHeader.getSecurityHeader(), sig
+				.getElement(), false);
+	}
+
+	/**
+	 * Prepend the BinarySecurityToken to the elements already in the Security
+	 * header.
+	 * 
+	 * The method can be called any time after <code>prepare()</code>.
+	 * This allows to insert the BST element at any position in the Security
+	 * header.
+	 * 
+	 * @param secHeader
+	 *            The security header that holds the BST element.
+	 */
+	public void prependBSTElementToHeader(WSSecHeader secHeader) {
+		if (bstToken != null) {
+			WSSecurityUtil.prependChildElement(document, secHeader.getSecurityHeader(),
+					bstToken.getElement(), false);
+		}
+		bstToken = null;
+	}
+
+	/**
+	 * Compute the Signature over the references.
+	 * 
+	 * After references are set this method computes the Signature for them.
+	 * This method can be called anytime after the references were set. See
+	 * <code>addReferencesToSign()</code>.
+	 * 
+	 * @throws WSSecurityException
+	 */
+	public void computeSignature() throws WSSecurityException {
+		WSDocInfoStore.store(wsDocInfo);
+		try {
+			if (keyIdentifierType == WSConstants.UT_SIGNING) {
+				sig.sign(sig.createSecretKey(secretKey));
+			} else {
+				sig.sign(crypto.getPrivateKey(user, password));
+			}
+			signatureValue = sig.getSignatureValue();
+		} catch (XMLSignatureException e1) {
+			throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+					null, null, e1);
+		} catch (Exception e1) {
+			throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+					null, null, e1);
+		} finally {
+			WSDocInfoStore.delete(wsDocInfo);
+		}
+
+	}
+
+	/**
+	 * Builds a signed soap envelope.
+	 * 
+	 * This is a convenience method and for backward compatibility. The method
+	 * creates a Signature and puts it into the Security header. It does so by
+	 * calling the single functions in order to perform a <i>one shot signature</i>.
+	 * This method is compatible with the build method of the previous version
+	 * with the exception of the additional WSSecHeader parameter.
+	 * 
+	 * @param doc
+	 *            The unsigned SOAP envelope as <code>Document</code>
+	 * @param cr
+	 *            An instance of the Crypto API to handle keystore and
+	 *            certificates
+	 * @param secHeader
+	 *            the security header element to hold the encrypted key element.
+	 * @return A signed SOAP envelope as <code>Document</code>
+	 * @throws WSSecurityException
+	 */
+	public Document build(Document doc, Crypto cr, WSSecHeader secHeader)
+			throws WSSecurityException {
+		doDebug = log.isDebugEnabled();
+
+		if (doDebug) {
+			log.debug("Beginning signing...");
+		}
+
+		Element securityHeader = secHeader.getSecurityHeader();
+
+		prepare(doc, cr, secHeader);
+
+		SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+				.getDocumentElement());
+
+		if (parts == null) {
+			parts = new Vector();
+			WSEncryptionPart encP = new WSEncryptionPart(soapConstants
+					.getBodyQName().getLocalPart(), soapConstants
+					.getEnvelopeURI(), "Content");
+			parts.add(encP);
+		}
+
+		addReferencesToSign(parts, secHeader);
+
+		prependToHeader(secHeader);
+
+		/*
+		 * if we have a BST prepend it in front of the Signature according to
+		 * strict layout rules.
+		 */
+		if (bstToken != null) {
+			prependBSTElementToHeader(secHeader);
+		}
+
+		computeSignature();
+
+		return (doc);
+	}
+
+	protected Element createSTRParameter(Document doc) {
+		Element transformParam = doc.createElementNS(WSConstants.WSSE_NS,
+				WSConstants.WSSE_PREFIX + ":TransformationParameters");
+
+		WSSecurityUtil.setNamespace(transformParam, WSConstants.WSSE_NS,
+				WSConstants.WSSE_PREFIX);
+
+		Element canonElem = doc.createElementNS(WSConstants.SIG_NS,
+				WSConstants.SIG_PREFIX + ":CanonicalizationMethod");
+
+		WSSecurityUtil.setNamespace(canonElem, WSConstants.SIG_NS,
+				WSConstants.SIG_PREFIX);
+
+		canonElem.setAttributeNS(null, "Algorithm",
+				Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+		transformParam.appendChild(canonElem);
+		return transformParam;
+	}
+
+	protected Set getInclusivePrefixes(Element target) {
+		return getInclusivePrefixes(target, true);
+	}
+
+	protected Set getInclusivePrefixes(Element target, boolean excludeVisible) {
+		Set result = new HashSet();
+		Node parent = target;
+		NamedNodeMap attributes;
+		Node attribute;
+		while (!(parent.getParentNode() instanceof Document)) {
+			parent = parent.getParentNode();
+			attributes = parent.getAttributes();
+			for (int i = 0; i < attributes.getLength(); i++) {
+				attribute = attributes.item(i);
+				if (attribute.getNamespaceURI() != null
+						&& attribute.getNamespaceURI().equals(
+								org.apache.ws.security.WSConstants.XMLNS_NS)) {
+					if (attribute.getNodeName().equals("xmlns")) {
+						result.add("#default");
+					} else {
+						result.add(attribute.getLocalName());
+					}
+				}
+			}
+		}
+
+		if (excludeVisible == true) {
+			attributes = target.getAttributes();
+			for (int i = 0; i < attributes.getLength(); i++) {
+				attribute = attributes.item(i);
+				if (attribute.getNamespaceURI() != null
+						&& attribute.getNamespaceURI().equals(
+								org.apache.ws.security.WSConstants.XMLNS_NS)) {
+					if (attribute.getNodeName().equals("xmlns")) {
+						result.remove("#default");
+					} else {
+						result.remove(attribute.getLocalName());
+					}
+				}
+				if (attribute.getPrefix() != null) {
+					result.remove(attribute.getPrefix());
+				}
+			}
+
+			if (target.getPrefix() == null) {
+				result.remove("#default");
+			} else {
+				result.remove(target.getPrefix());
+			}
+		}
+
+		return result;
+	}
+}
diff --git a/src/org/apache/ws/security/message/WSSecSignatureConfirmation.java b/src/org/apache/ws/security/message/WSSecSignatureConfirmation.java
new file mode 100644
index 0000000..d54a255
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecSignatureConfirmation.java
@@ -0,0 +1,132 @@
+/*

+ * Copyright  2003-2005 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.message.token.SignatureConfirmation;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+

+/**

+ * Builds a WS SignatureConfirmation and inserts it into the SOAP Envelope.

+ * 

+ * @author Werner Dittmann (Werner.Dittmann@t-online.de).

+ */

+

+public class WSSecSignatureConfirmation extends WSSecBase {

+    private static Log log = LogFactory.getLog(WSSecSignatureConfirmation.class

+            .getName());

+

+    private SignatureConfirmation sc = null;

+

+    private Document document = null;

+    

+    byte[] signatureValue = null;

+

+    /**

+     * Constructor.

+     */

+    public WSSecSignatureConfirmation() {

+    }

+

+	/**

+	 * Set the Signature value to store in this SignatureConfirmation.

+	 * 

+	 * @param signatureValue

+	 *            The Signature value to store in the SignatureConfirmation

+	 *            element

+	 */

+	public void setSignatureValue(byte[] signatureValue) {

+		this.signatureValue = signatureValue;

+	}

+

+

+	/**

+	 * Creates a SignatureConfimation element.

+	 * 

+	 * The method prepares and initializes a WSSec SignatureConfirmation structure after

+	 * the relevant information was set. Before calling <code>prepare()</code> the

+	 * filed <code>signatureValue</code> must be set

+	 * 

+	 * @param doc

+	 *            The SOAP enevlope as W3C document

+	 */

+	public void prepare(Document doc) {

+		document = doc;

+        sc = new SignatureConfirmation(doc, signatureValue);;

+		String scId = "SigConf-" + sc.hashCode();

+		sc.setID(scId);

+	}

+    

+	/**

+	 * Prepends the SignatureConfirmation element to the elements already in the

+	 * Security header.

+	 * 

+	 * The method can be called any time after <code>prepare()</code>.

+	 * This allows to insert the SignatureConfirmation element at any position in the

+	 * Security header.

+	 * 

+	 * @param secHeader

+	 *            The security header that holds the Signature element.

+	 */

+	public void prependToHeader(WSSecHeader secHeader) {

+		WSSecurityUtil.prependChildElement(document, secHeader

+				.getSecurityHeader(), sc.getElement(), false);

+	}

+    

+    /**

+     * Adds a new <code>SignatureConfirmation</code> to a soap envelope.

+     * 

+     * A complete <code>SignatureConfirmation</code> is constructed and added

+     * to the <code>wsse:Security</code> header.

+     * 

+     * @param doc

+     *            The SOAP enevlope as W3C document

+     * @param sigVal

+     *            the Signature value. This will be the content of the "Value"

+     *            attribute.

+ 	 * @param secHeader

+	 *            The security header that holds the Signature element.

+    * @return Document with SignatureConfirmation added

+     */

+    public Document build(Document doc, byte[] sigVal, WSSecHeader secHeader) {

+        log.debug("Begin add signature confirmation...");

+        

+        signatureValue = sigVal;

+		prepare(doc);

+		prependToHeader(secHeader);

+        

+        return doc;

+    }

+

+	/**

+	 * Get the id generated during <code>prepare()</code>.

+	 * 

+	 * Returns the the value of wsu:Id attribute of this SignatureConfirmation. 

+	 * 

+	 * @return Return the wsu:Id of this token or null if <code>prepareToken()</code>

+	 * was not called before.

+	 */

+    public String getId() {

+    	if (sc == null) {

+    		return null;

+    	}

+        return sc.getID();

+    }

+}

diff --git a/src/org/apache/ws/security/message/WSSecTimestamp.java b/src/org/apache/ws/security/message/WSSecTimestamp.java
new file mode 100644
index 0000000..decea44
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecTimestamp.java
@@ -0,0 +1,132 @@
+/*

+ * Copyright  2003-2005 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.message.token.Timestamp;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+

+/**

+ * Builds a WS Timestamp and inserts it into the SOAP Envelope. Refer to the WS

+ * specification 1.0. chapter 10 / appendix A.2

+ * 

+ * @author Christof Soehngen (Christof.Soehngen@syracom.de).

+ * @author Werner Dittmann (werner@apache.org).

+ */

+

+public class WSSecTimestamp extends WSSecBase {

+    private static Log log = LogFactory.getLog(WSSecTimestamp.class.getName());

+

+    private Timestamp ts = null;

+

+    private Document document = null;

+

+    private int timeToLive = 300; // time between Created and Expires

+

+    /**

+     * Constructor.

+     */

+    public WSSecTimestamp() {

+    }

+

+    /**

+     * Set the time to live. This is the time difference in seconds between the

+     * <code>Created</code> and the <code>Expires</code> in

+     * <code>Timestamp</code>. <p/>

+     * 

+     * @param ttl

+     *            The time to live in second

+     */

+    public void setTimeToLive(int ttl) {

+        timeToLive = ttl;

+    }

+

+    /**

+     * Creates a Timestamp element.

+     * 

+     * The method prepares and initializes a WSSec Timestamp structure after the

+     * relevant information was set. Before calling <code>prepare()</code> the

+     * parameter such as <code>timeToLive</code> can be set if the deafult

+     * value is not suitable.

+     * 

+     * @param doc

+     *            The SOAP enevlope as W3C document

+     */

+    public void prepare(Document doc) {

+        document = doc;

+        ts = new Timestamp(wssConfig.isPrecisionInMilliSeconds(), doc,

+                timeToLive);

+        String tsId = "Timestamp-" + ts.hashCode();

+        ts.setID(tsId);

+    }

+

+    /**

+     * Prepends the Timestamp element to the elements already in the Security

+     * header.

+     * 

+     * The method can be called any time after <code>prepare()</code>. This

+     * allows to insert the Timestamp element at any position in the Security

+     * header.

+     * 

+     * @param secHeader

+     *            The security header that holds the Signature element.

+     */

+    public void prependToHeader(WSSecHeader secHeader) {

+        WSSecurityUtil.prependChildElement(document, secHeader

+                .getSecurityHeader(), ts.getElement(), false);

+    }

+

+    /**

+     * Adds a new <code>Timestamp</code> to a soap envelope.

+     * 

+     * A complete <code>Timestamp</code> is constructed and added to the

+     * <code>wsse:Security</code> header.

+     * 

+     * @param doc

+     *            The SOAP enevlope as W3C document

+     * @param secHeader

+     *            The security header that hold this Timestamp

+     * @return Document with Timestamp added

+     * @throws Exception

+     */

+    public Document build(Document doc, WSSecHeader secHeader) {

+        log.debug("Begin add timestamp...");

+

+        prepare(doc);

+        prependToHeader(secHeader);

+

+        return doc;

+    }

+

+    /**

+     * Get the id generated during <code>prepare()</code>.

+     * 

+     * Returns the the value of wsu:Id attribute of this Timestamp.

+     * 

+     * @return Return the wsu:Id of this token or null if

+     *         <code>prepareToken()</code> was not called before.

+     */

+    public String getId() {

+        if (ts == null) {

+            return null;

+        }

+        return ts.getID();

+    }

+}

diff --git a/src/org/apache/ws/security/message/WSSecUsernameToken.java b/src/org/apache/ws/security/message/WSSecUsernameToken.java
new file mode 100644
index 0000000..7f6b6df
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSecUsernameToken.java
@@ -0,0 +1,189 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.message.token.UsernameToken;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+

+/**

+ * Builds a WS UsernameToken.

+ * 

+ * Refer to the WS specification, UsernameToken profile

+ * 

+ * @author Werner Dittmann (werner@apache.org).

+ */

+

+public class WSSecUsernameToken extends WSSecBase {

+	private static Log log = LogFactory.getLog(WSSecUsernameToken.class

+			.getName());

+

+	private String passwordType = WSConstants.PASSWORD_DIGEST;

+

+	private UsernameToken ut = null;

+

+	private String id = null;

+

+	private boolean nonce = false;

+

+	private boolean created = false;

+

+	private Document document = null;

+

+	/**

+	 * Constructor.

+	 */

+	public WSSecUsernameToken() {

+	}

+

+	/**

+	 * Defines how to construct the password element of the

+	 * <code>UsernameToken</code>.

+	 * 

+	 * @param pwType

+	 *            contains the password type. Only allowed values are

+	 *            {@link WSConstants#PASSWORD_DIGEST} and

+	 *            {@link WSConstants#PASSWORD_TEXT}.

+	 */

+	public void setPasswordType(String pwType) {

+		if (pwType == null) {

+			passwordType = WSConstants.PASSWORD_DIGEST;

+		} else if (pwType.equals(WSConstants.PASSWORD_DIGEST)

+				|| pwType.equals(WSConstants.PASSWORD_TEXT)) {

+			passwordType = pwType;

+		}

+	}

+

+	/**

+	 * Add a Nonce element to the UsernameToken.

+	 */

+	public void addNonce() {

+		nonce = true;

+	}

+

+	/**

+	 * Add a Created element to the UsernameToken.

+	 */

+	public void addCreated() {

+		created = true;

+	}

+

+	

+	/**

+	 * Get the derived secret key.

+	 * 

+	 * After the <code>prepare()</code> method was called use this method

+	 * to compute a derived secret key. The generation of this secret key is according

+	 * to WS-Trust specification.

+	 * 

+	 * @return Return the derived secret key of this token or null if <code>prepare()</code>

+	 * was not called before.

+	 */

+	public byte[] getSecretKey() {

+		if (ut == null) {

+			return null;

+		}

+		return ut.getSecretKey();

+	}

+

+	/**

+	 * Get the id generated during <code>prepare()</code>.

+	 * 

+	 * Returns the the value of wsu:Id attribute of this UsernameToken. 

+	 * 

+	 * @return Return the wsu:Id of this token or null if <code>prepare()</code>

+	 * was not called before.

+	 */

+	public String getId() {

+		if (ut == null) {

+			return null;

+		}

+		return ut.getID();

+	}

+

+	/**

+	 * Creates a Username token.

+	 * 

+	 * The method prepares and initializes a WSSec UsernameToken structure after

+	 * the relevant information was set. A Before calling

+	 * <code>prepare()</code> all parameters such as user, password,

+	 * passwordType etc. must be set. A complete <code>UsernameToken</code> is

+	 * constructed.

+	 * 

+	 * @param doc

+	 *            The SOAP enevlope as W3C document

+	 */

+	public void prepare(Document doc) {

+		document = doc;

+		ut = new UsernameToken(wssConfig.isPrecisionInMilliSeconds(), doc,

+				passwordType);

+		ut.setName(user);

+		ut.setPassword(password);

+		String utId = "UsernameToken-" + ut.hashCode();

+		ut.setID(utId);

+		if (nonce) {

+			ut.addNonce(doc);

+		}

+		if (created) {

+			ut.addCreated(wssConfig.isPrecisionInMilliSeconds(), doc);

+		}

+	}

+

+	/**

+	 * Prepends the UsernameToken element to the elements already in the

+	 * Security header.

+	 * 

+	 * The method can be called any time after <code>prepare()</code>.

+	 * This allows to insert the UsernameToken element at any position in the

+	 * Security header.

+	 * 

+	 * @param secHeader

+	 *            The security header that holds the Signature element.

+	 */

+	public void prependToHeader(WSSecHeader secHeader) {

+		WSSecurityUtil.prependChildElement(document, secHeader

+				.getSecurityHeader(), ut.getElement(), false);

+	}

+

+	/**

+	 * Adds a new <code>UsernameToken</code> to a soap envelope.

+	 * 

+	 * Before calling <code>build()</code> all parameters such as user,

+	 * password, passwordType etc. must be set. A complete

+	 * <code>UsernameToken</code> is constructed and added to the

+	 * <code>wsse:Security</code> header.

+	 * 

+	 * @param doc

+	 *            The SOAP enevlope as W3C document

+	 * @param secHeader

+	 *            The security header inside the SOAP envelope

+	 * @return Document with UsernameToken added

+	 */

+	public Document build(Document doc, WSSecHeader secHeader) {

+		log.debug("Begin add username token...");

+

+		prepare(doc);

+		prependToHeader(secHeader);

+

+		return doc;

+	}

+

+}

diff --git a/src/org/apache/ws/security/message/WSSignEnvelope.java b/src/org/apache/ws/security/message/WSSignEnvelope.java
new file mode 100644
index 0000000..9669ced
--- /dev/null
+++ b/src/org/apache/ws/security/message/WSSignEnvelope.java
@@ -0,0 +1,640 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.PKIPathSecurity;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.transform.STRTransform;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.transforms.TransformationException;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.transforms.params.InclusiveNamespaces;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Signs a SOAP envelope according to WS Specification, X509 profile, and adds
+ * the signature data.
+ *
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (Werner.Dittman@siemens.com)
+ */
+public class WSSignEnvelope extends WSBaseMessage {
+
+    private static Log log = LogFactory.getLog(WSSignEnvelope.class.getName());
+
+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");
+
+    protected boolean useSingleCert = true;
+
+    protected String sigAlgo = null;
+
+    protected String canonAlgo = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
+
+    protected WSSAddUsernameToken usernameToken = null;
+
+    protected byte[] signatureValue = null;
+
+    /**
+     * Constructor.
+     * @deprecated replaced by {@link WSSecSignature#WSSecSignature()}
+     */
+    public WSSignEnvelope() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param actor The actor name of the <code>wsse:Security</code> header
+     * 
+     * @deprecated replaced by {@link WSSecSignature#WSSecSignature()}
+     *             and {@link WSSecHeader} for actor specification.
+     */
+    public WSSignEnvelope(String actor) {
+        super(actor);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param actor The actor name of the <code>wsse:Security</code> header
+     * @param mu    Set <code>mustUnderstand</code> to true or false
+     * 
+     * @deprecated replaced by {@link WSSecSignature#WSSecSignature()}
+     *             and {@link WSSecHeader} for actor and mustunderstand
+     *             specification.
+     */
+    public WSSignEnvelope(String actor, boolean mu) {
+        super(actor, mu);
+    }
+
+    /**
+     * set the single cert flag.
+     *
+     * @param useSingleCert
+     * @deprecated replaced by {@link WSSecSignature#setUseSingleCertificate(boolean)}
+     */
+    public void setUseSingleCertificate(boolean useSingleCert) {
+        this.useSingleCert = useSingleCert;
+    }
+
+    /**
+     * Get the single cert flag.
+     *
+     * @return If to use a single cert
+     * @deprecated replaced by {@link WSSecSignature#isUseSingleCertificate()}
+     */
+    public boolean isUseSingleCertificate() {
+        return this.useSingleCert;
+    }
+
+    /**
+     * Set the name of the signature encryption algorithm to use.
+     *
+     * If the algorithm is not set then Triple RSA is used. Refer to WSConstants
+     * which algorithms are supported.
+     *
+     * @param algo
+     *            Is the name of the signature algorithm
+     * @see WSConstants#RSA
+     * @see WSConstants#DSA
+     * @deprecated replaced by {@link WSSecSignature#setSignatureAlgorithm(String)}
+     */
+    public void setSignatureAlgorithm(String algo) {
+        sigAlgo = algo;
+    }
+
+    /**
+     * Get the name of the signature algorithm that is being used.
+     *
+     * If the algorithm is not set then RSA is default.
+     *
+     * @return the identifier URI of the signature algorithm
+     * @deprecated replaced by {@link WSSecSignature#getSignatureAlgorithm()}
+     */
+    public String getSignatureAlgorithm() {
+        return sigAlgo;
+    }
+
+    /**
+     * Set the canonicalization method to use.
+     *
+     * If the canonicalization method is not set then the recommended Exclusive
+     * XML Canonicalization is used by default Refer to WSConstants which
+     * algorithms are supported.
+     *
+     * @param algo
+     *            Is the name of the signature algorithm
+     * @see WSConstants#C14N_OMIT_COMMENTS
+     * @see WSConstants#C14N_WITH_COMMENTS
+     * @see WSConstants#C14N_EXCL_OMIT_COMMENTS
+     * @see WSConstants#C14N_EXCL_WITH_COMMENTS
+     * @deprecated replaced by {@link WSSecSignature#setSigCanonicalization(String)}
+     */
+    public void setSigCanonicalization(String algo) {
+        canonAlgo = algo;
+    }
+
+    /**
+     * Get the canonicalization method.
+     *
+     * If the canonicalization method was not set then Exclusive XML
+     * Canonicalization is used by default.
+     *
+     * @return TODO
+     * @deprecated replaced by {@link WSSecSignature#getSigCanonicalization()}
+     */
+    public String getSigCanonicalization() {
+        return canonAlgo;
+    }
+
+    /**
+     * @param usernameToken The usernameToken to set.
+     * @deprecated replaced by {@link WSSecSignature#setUsernameToken(WSSecUsernameToken)}
+     */
+    public void setUsernameToken(WSSAddUsernameToken usernameToken) {
+        this.usernameToken = usernameToken;
+    }
+
+    /**
+     * @return Returns the signatureValue.
+     * @deprecated replaced by {@link WSSecSignature#getSignatureValue()}
+     */
+    public byte[] getSignatureValue() {
+        return signatureValue;
+    }
+
+    /**
+     * Builds a signed soap envelope.
+     *
+     * The method first gets an appropriate
+     * security header. According to the defined parameters for certificate
+     * handling the signature elements are constructed and inserted into the
+     * <code>wsse:Signature</code>
+     *
+     * @param doc    The unsigned SOAP envelope as <code>Document</code>
+     * @param crypto An instance of the Crypto API to handle keystore and
+     *               certificates
+     * @return A signed SOAP envelope as <code>Document</code>
+     * @throws WSSecurityException
+     * @deprecated replaced by {@link WSSecSignature#build(Document, Crypto, WSSecHeader)}
+     */
+    public Document build(Document doc, Crypto crypto)
+            throws WSSecurityException {
+        doDebug = log.isDebugEnabled();
+
+        long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+        if (tlog.isDebugEnabled()) {
+            t0 = System.currentTimeMillis();
+        }
+        if (doDebug) {
+            log.debug("Beginning signing...");
+        }
+
+        /*
+         * Gather some info about the document to process and store it for
+         * retrival
+         */
+        WSDocInfo wsDocInfo = new WSDocInfo(doc.hashCode());
+        wsDocInfo.setCrypto(crypto);
+
+        Element envelope = doc.getDocumentElement();
+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
+
+        Element securityHeader = insertSecurityHeader(doc);
+
+        // Set the id of the elements to be used as digest source
+        // String id = setBodyID(doc);
+        String certUri = null;
+        X509Certificate[] certs = null;
+        if (keyIdentifierType != WSConstants.UT_SIGNING) {
+            certs = crypto.getCertificates(user);
+            if (certs == null || certs.length <= 0) {
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "invalidX509Data", new Object[] { "for Signature" });
+            }
+            certUri = "CertId-" + certs[0].hashCode();
+            if (sigAlgo == null) {
+                String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
+                log.debug("automatic sig algo detection: " + pubKeyAlgo);
+                if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+                    sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+                } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
+                    sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
+                } else {
+                    throw new WSSecurityException(
+                            WSSecurityException.FAILURE,
+                            "invalidX509Data",
+                            new Object[] { "for Signature - unkown public key Algo" });
+                }
+            }
+        }
+        XMLSignature sig = null;
+
+        if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
+            Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
+                    Constants._TAG_CANONICALIZATIONMETHOD);
+
+            canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);
+
+            if (wssConfig.isWsiBSPCompliant()) {
+                Set prefixes = getInclusivePrefixes(securityHeader, false);
+
+                InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(
+                        doc, prefixes);
+
+                canonElem.appendChild(inclusiveNamespaces.getElement());
+            }
+
+            try {
+                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(
+                        doc, sigAlgo);
+                sig = new XMLSignature(doc, null, signatureAlgorithm
+                        .getElement(), canonElem);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        } else {
+            try {
+                sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
+            } catch (XMLSecurityException e) {
+                log.error("", e);
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");
+            }
+        }
+        /*
+         * If we don't generate a new Transforms for each addDocument here, then
+         * only the last Transforms is put into the according ds:Reference
+         * element, i.e. the first ds:Reference does not contain a Transforms
+         * element. Thus the verification fails (somehow)
+         */
+
+        KeyInfo info = sig.getKeyInfo();
+        String keyInfoUri = "KeyId-" + info.hashCode();
+        info.setId(keyInfoUri);
+
+        SecurityTokenReference secRef = new SecurityTokenReference(doc);
+        String strUri = "STRId-" + secRef.hashCode();
+        secRef.setID(strUri);
+
+        if (tlog.isDebugEnabled()) {
+            t1 = System.currentTimeMillis();
+        }
+
+        if (parts == null) {
+            parts = new Vector();
+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants
+                    .getBodyQName().getLocalPart(), soapConstants
+                    .getEnvelopeURI(), "Content");
+            parts.add(encP);
+        }
+
+        Transforms transforms = null;
+
+        for (int part = 0; part < parts.size(); part++) {
+            WSEncryptionPart encPart = (WSEncryptionPart) parts.get(part);
+
+            String idToSign = encPart.getId();
+
+            String elemName = encPart.getName();
+            String nmSpace = encPart.getNamespace();
+
+            /*
+             * Set up the elements to sign. There are two resevered element
+             * names: "Token" and "STRTransform" "Token": Setup the Signature to
+             * either sign the information that points to the security token or
+             * the token itself. If its a direct reference sign the token,
+             * otherwise sign the KeyInfo Element. "STRTransform": Setup the
+             * ds:Reference to use STR Transform
+             *
+             */
+            try {
+                if (idToSign != null) {
+                	Element toSignById = WSSecurityUtil
+							.findElementById(doc.getDocumentElement(),
+									idToSign, WSConstants.WSU_NS);
+					if (toSignById == null) {
+						toSignById = WSSecurityUtil.findElementById(doc
+								.getDocumentElement(), idToSign, null);
+					}
+                    transforms = new Transforms(doc);
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(doc,
+                                        getInclusivePrefixes(toSignById))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + idToSign, transforms);
+                }
+                else if (elemName.equals("Token")) {
+                    transforms = new Transforms(doc);
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {
+                        if (wssConfig.isWsiBSPCompliant()) {
+                            transforms
+                                    .item(0)
+                                    .getElement()
+                                    .appendChild(
+                                            new InclusiveNamespaces(
+                                                    doc,
+                                                    getInclusivePrefixes(securityHeader))
+                                                    .getElement());
+                        }
+                        sig.addDocument("#" + certUri, transforms);
+                    } else {
+                        if (wssConfig.isWsiBSPCompliant()) {
+                            transforms.item(0).getElement().appendChild(
+                                    new InclusiveNamespaces(doc,
+                                            getInclusivePrefixes(info
+                                                    .getElement()))
+                                            .getElement());
+                        }
+                        sig.addDocument("#" + keyInfoUri, transforms);
+                    }
+                } else if (elemName.equals("STRTransform")) { // STRTransform
+                    Element ctx = createSTRParameter(doc);
+                    transforms = new Transforms(doc);
+                    transforms.addTransform(
+                            STRTransform.implementedTransformURI, ctx);
+                    sig.addDocument("#" + strUri, transforms);
+                } else if (elemName.equals("Assertion")) { // Assertion
+
+                    String id = null;
+                    id = SAMLUtil.getAssertionId(envelope, elemName, nmSpace);
+
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envelope, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms = new Transforms(doc);
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(doc,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    String prefix = WSSecurityUtil.setNamespace(body,
+                            WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+                    body.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id",
+                            id);
+                    sig.addDocument("#" + id, transforms);
+
+                } else {
+                    Element body = (Element) WSSecurityUtil.findElement(
+                            envelope, elemName, nmSpace);
+                    if (body == null) {
+                        throw new WSSecurityException(
+                                WSSecurityException.FAILURE, "noEncElement",
+                                new Object[] { nmSpace + ", " + elemName });
+                    }
+                    transforms = new Transforms(doc);
+                    transforms
+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    if (wssConfig.isWsiBSPCompliant()) {
+                        transforms.item(0).getElement().appendChild(
+                                new InclusiveNamespaces(doc,
+                                        getInclusivePrefixes(body))
+                                        .getElement());
+                    }
+                    sig.addDocument("#" + setWsuId(body), transforms);
+                }
+            } catch (TransformationException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            } catch (XMLSignatureException e1) {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
+                        e1);
+            }
+        }
+
+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());
+
+        WSSecurityUtil.prependChildElement(doc, securityHeader, sig
+                .getElement(), false);
+        if (tlog.isDebugEnabled()) {
+            t2 = System.currentTimeMillis();
+        }
+
+        byte[] secretKey = null;
+        switch (keyIdentifierType) {
+        case WSConstants.BST_DIRECT_REFERENCE:
+            Reference ref = new Reference(doc);
+            ref.setURI("#" + certUri);
+            BinarySecurity bstToken = null;
+            if (!useSingleCert) {
+                bstToken = new PKIPathSecurity(doc);
+                ((PKIPathSecurity) bstToken).setX509Certificates(certs, false,
+                        crypto);
+            } else {
+                bstToken = new X509Security(doc);
+                ((X509Security) bstToken).setX509Certificate(certs[0]);
+            }
+            ref.setValueType(bstToken.getValueType());
+            secRef.setReference(ref);
+            bstToken.setID(certUri);
+            WSSecurityUtil.prependChildElement(doc, securityHeader, bstToken
+                    .getElement(), false);
+            wsDocInfo.setBst(bstToken.getElement());
+            break;
+
+        case WSConstants.ISSUER_SERIAL:
+            XMLX509IssuerSerial data = new XMLX509IssuerSerial(doc, certs[0]);
+            X509Data x509Data = new X509Data(doc);
+            x509Data.add(data);
+            secRef.setX509IssuerSerial(x509Data);
+            break;
+
+        case WSConstants.X509_KEY_IDENTIFIER:
+            secRef.setKeyIdentifier(certs[0]);
+            break;
+
+        case WSConstants.SKI_KEY_IDENTIFIER:
+            secRef.setKeyIdentifierSKI(certs[0], crypto);
+            break;
+
+        case WSConstants.UT_SIGNING:
+            Reference refUt = new Reference(doc);
+            refUt.setValueType(WSConstants.USERNAMETOKEN_NS + "#UsernameToken");
+            String utId = usernameToken.getId();
+            if (utId == null) {
+                utId = "usernameTokenId-" + usernameToken.hashCode();
+                usernameToken.setId(utId);
+            }
+            refUt.setURI("#" + utId);
+            secRef.setReference(refUt);
+            secretKey = usernameToken.getSecretKey();
+            break;
+
+        case WSConstants.THUMBPRINT_IDENTIFIER:
+            secRef.setKeyIdentifierThumb(certs[0]);
+            break;
+
+        default:
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "unsupportedKeyId");
+        }
+        if (tlog.isDebugEnabled()) {
+            t3 = System.currentTimeMillis();
+        }
+        info.addUnknownElement(secRef.getElement());
+
+        WSDocInfoStore.store(wsDocInfo);
+        try {
+            if (keyIdentifierType == WSConstants.UT_SIGNING) {
+                sig.sign(sig.createSecretKey(secretKey));
+            } else {
+                sig.sign(crypto.getPrivateKey(user, password));
+            }
+            signatureValue = sig.getSignatureValue();
+        } catch (XMLSignatureException e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } catch (Exception e1) {
+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
+                    null, null, e1);
+        } finally {
+            WSDocInfoStore.delete(wsDocInfo);
+        }
+        if (tlog.isDebugEnabled()) {
+            t4 = System.currentTimeMillis();
+            tlog.debug("SignEnvelope: cre-Sig= " + (t1 - t0)
+                    + " set transform= " + (t2 - t1) + " sec-ref= " + (t3 - t2)
+                    + " signature= " + (t4 - t3));
+        }
+        if (doDebug) {
+            log.debug("Signing complete.");
+        }
+        return (doc);
+    }
+
+    protected Element createSTRParameter(Document doc) {
+        Element transformParam = doc.createElementNS(WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX + ":TransformationParameters");
+
+        WSSecurityUtil.setNamespace(transformParam, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        Element canonElem = doc.createElementNS(WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX + ":CanonicalizationMethod");
+
+        WSSecurityUtil.setNamespace(canonElem, WSConstants.SIG_NS,
+                WSConstants.SIG_PREFIX);
+
+        canonElem.setAttributeNS(null, "Algorithm",
+                Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+        transformParam.appendChild(canonElem);
+        return transformParam;
+    }
+
+    protected Set getInclusivePrefixes(Element target) {
+        return getInclusivePrefixes(target, true);
+    }
+
+    protected Set getInclusivePrefixes(Element target, boolean excludeVisible) {
+        Set result = new HashSet();
+        Node parent = target;
+        NamedNodeMap attributes;
+        Node attribute;
+        while (!(parent.getParentNode() instanceof Document)) {
+            parent = parent.getParentNode();
+            attributes = parent.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.add("#default");
+                    } else {
+                        result.add(attribute.getLocalName());
+                    }
+                }
+            }
+        }
+
+        if (excludeVisible == true) {
+            attributes = target.getAttributes();
+            for (int i = 0; i < attributes.getLength(); i++) {
+                attribute = attributes.item(i);
+                if (attribute.getNamespaceURI() != null
+                        && attribute.getNamespaceURI().equals(
+                                org.apache.ws.security.WSConstants.XMLNS_NS)) {
+                    if (attribute.getNodeName().equals("xmlns")) {
+                        result.remove("#default");
+                    } else {
+                        result.remove(attribute.getLocalName());
+                    }
+                }
+                if (attribute.getPrefix() != null) {
+                    result.remove(attribute.getPrefix());
+                }
+            }
+
+            if (target.getPrefix() == null) {
+                result.remove("#default");
+            } else {
+                result.remove(target.getPrefix());
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/src/org/apache/ws/security/message/package.html b/src/org/apache/ws/security/message/package.html
new file mode 100644
index 0000000..a5ab68a
--- /dev/null
+++ b/src/org/apache/ws/security/message/package.html
@@ -0,0 +1,149 @@
+<!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

+  -->

+<html>

+<head>

+  <title>Web Service Security classes for message creation</title>

+<!--

+

+  @(#)Web Service Security classes for message creation 

+

+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.

+ *

+ */

+-->

+</head>

+<body bgcolor="white">

+

+The package provides classes to create messages that are compliant to the

+OASIS Web Service Security specifications.

+<p/>

+The OASIS WSS specifications define a number of features and it is possible 

+to combine them in several ways. The WSS4J classes already support 

+a large number of WSS features and their combinations. 

+<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss">

+Here</a> are the WSS specifications.

+<p/>

+Currently this package contains two sets of classes that provide the same 

+or similar functionality. 

+<ul>

+  <li>The old classes, named WSAdd*, WSEncryptBody, WSSignEnvelope, WSBaseMessage.

+  The usage of these classes is depreciated.</li>

+  <li>The new, refactored classes. Their names start with the prefix <e>WSSec</e>.

+</ul>

+

+<h3>How to use the WSSec* classes</h3>

+The new refactored classes follow the same usage pattern. 

+<ol type="1">

+  <li>Create an object for the required security element, for example a 

+  <code>WSSecSignature</code>.

+  </li>

+  <li>Set the required fields using setter methods, for example user name, signature

+  algorithm, etc.

+  </li>

+  <li>After the fields are set call <code>prepare(...)</code>. This initializes the internal

+  structures, gets the required data like X509 tokens, etc.

+  </li>

+  <li>After preparation you may do security element specific functions, for example add

+  data refernces that should be included in the signature. You can also add the element to

+  the <code>WSSecHeader</code> at this time (adding to the security header can be done at any

+  time after <code>prepare(...)</code>). See the documentation of the various classes what is

+  available.

+  </li>

+</ol>

+In contrast to the old classes the handling of the security header is not longer

+implicitly performed. To provide better flexibilty the class <code>WSSecHeader</code>

+deals with the security header.

+<p/>

+The new structure of the classes provide a much more flxible handling of the actions

+performed by the classes. This enhanced flexibility enables a precise control of

+the placement of security elements in the security header and a much better control

+which elements to sign or to encrypt.

+<p/>

+This code snippet shows how to setup a Signature element:

+<pre>

+        /*

+         * Explicit security header handling. The WSSecHeader object

+         * remains the same for all elements that shall go into this

+         * security header. Thus you usually need to created one

+         * WSSecHeader object only.

+         */

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+

+        WSSecSignature builder = new WSSecSignature();

+

+        builder.setUserInfo("username", "password");

+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);

+

+        Document doc = getSOAPEnvelope();

+

+		builder.prepare(doc, crypto, secHeader);

+

+		/*

+		 * Set parts to sign

+		 */

+		Vector parts = new Vector();

+		WSEncryptionPart encP = new WSEncryptionPart(localName, namespace, "Content");

+		parts.add(encP);

+

+		/*

+		 * Add the references to include into Signature. This can be done multiple

+		 * times.

+		 */

+		builder.addReferencesToSign(parts, secHeader);

+

+		/*

+		 * Add the Signature now to the security header

+		 */

+		builder.prependToHeader(secHeader);

+

+		/*

+		 * There maybe a BST to prepend it in front of the Signature according to

+		 * strict layout rules.

+		 */

+		builder.prependBSTElementToHeader(secHeader);

+

+		/*

+		 * Before calling computeSignature make sure all elements to sign are

+		 * available in the document (SOAP Envelope)

+		 */

+		builder.computeSignature();

+

+</pre>

+Each new class also contains a <code>build()</code> method that is similar to the

+<code>build()</code> method in the old classes. Thus, if the flexibilty is not

+required you may use this method for convenience.

+

+<h3>Each top level security element has wsu:Id or plain Id attribute</h3>

+The <code>prepare()</code> method autmatically generates an Id string for each new

+element and sets the wsu:Id or plain Id attribute. Which type 

+of Id to use is determined by the security element. The <e>EncryptedKey</e> and <e>Signature</e> 

+elements have a plain Id according to the W3C specifications, elements defined by 

+the OASIS WS Security specifications contain a wsu:Id. 

+<p/>

+Each <code>WSSec*</code> class has a <code>getId()</code> that returns the id strig

+regardless if its qualified or not.

+<p/>

+The security processing uses these Id to identify each top level security element to

+provide additional further processing of an element, for example to encrypt a Signature or

+any other top level element. Also a Signature may include each top level element. Which

+parts of a message to sign and/or encrypt is controlled by the Security Policy

+

+@since WSS4J 2.0

+</body>

+</html>

diff --git a/src/org/apache/ws/security/message/token/BinarySecurity.java b/src/org/apache/ws/security/message/token/BinarySecurity.java
new file mode 100644
index 0000000..5477ae6
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/BinarySecurity.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Binary Security Token.
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com).
+ * @author Werner Dittmann (Werner.Dittmann@t-onile.de).
+ */
+public class BinarySecurity {
+    public static final QName TOKEN_BST = new QName(WSConstants.WSSE_NS, "BinarySecurityToken");
+    public static final QName TOKEN_KI = new QName(WSConstants.WSSE_NS, "KeyIdentifier");
+    public static final String BASE64_ENCODING = WSConstants.SOAPMESSAGE_NS + "#Base64Binary";
+    protected Element element = null;
+
+    /**
+     * Constructor.
+     * <p/>
+     * 
+     * @param elem 
+     * @throws WSSecurityException 
+     */
+    public BinarySecurity(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(), this.element
+                .getLocalName());
+        if (!el.equals(TOKEN_BST) && !el.equals(TOKEN_KI)) {
+            throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY_TOKEN, "badTokenType",
+                    new Object[] { el });
+        }
+        String encoding = getEncodingType();
+        /*
+         * if the Element is a BinarySecurityToken then
+         *     encoding may be null -> default is Base64
+         *     if encoding is not null and not empty it must be Base64
+         * else
+         *     this is a keyidentifier element
+         *     must contain an encoding attribute which must be Base64
+         *     in this case
+         */
+        if (el.equals(TOKEN_BST)) {
+            if (encoding != null && encoding.length() > 0
+                    && !encoding.equals(BASE64_ENCODING)) {
+                throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY_TOKEN,
+                        "badEncoding", new Object[] { encoding });
+            }
+        } else if (el.equals(TOKEN_KI)) {
+            if (encoding == null || !encoding.equals(BASE64_ENCODING)) {
+                throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY_TOKEN,
+                        "badEncoding", new Object[] { encoding });
+            }
+        }
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param doc 
+     */
+    public BinarySecurity(Document doc) {
+        this.element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:BinarySecurityToken");
+        WSSecurityUtil.setNamespace(this.element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
+        setEncodingType(BASE64_ENCODING);
+        this.element.appendChild(doc.createTextNode(""));
+    }
+
+    /**
+     * get the value type.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String getValueType() {
+        return this.element.getAttribute("ValueType");
+    }
+
+    /**
+     * set the value type.
+     * <p/>
+     * 
+     * @param type 
+     */
+    protected void setValueType(String type) {
+        this.element.setAttributeNS(null, "ValueType", type);
+    }
+
+    /**
+     * get the encoding type.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String getEncodingType() {
+        return this.element.getAttribute("EncodingType");
+    }
+
+    /**
+     * set the encoding type.
+     * <p/>
+     * 
+     * @param encoding 
+     */
+    protected void setEncodingType(String encoding) {
+        this.element.setAttributeNS(null, "EncodingType", encoding);
+    }
+
+    /**
+     * get the byte array containing token information.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public byte[] getToken() {
+        Text node = getFirstNode();
+        if (node == null) {
+            return null;
+        }
+        try {
+            return Base64.decode(node.getData());
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * set the token information.
+     * <p/>
+     * 
+     * @param data 
+     */
+    protected void setToken(byte[] data) {
+        if (data == null) {
+            throw new IllegalArgumentException("data == null");
+        }
+        Text node = getFirstNode();
+        node.setData(Base64.encode(data));
+    }
+
+    /**
+     * return the first text node.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    protected Text getFirstNode() {
+        Node node = this.element.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * return the dom element.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * get the id.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * set the id.
+     * <p/>
+     * 
+     * @param id 
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+    /**
+     * return the string representation of the token.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+}
diff --git a/src/org/apache/ws/security/message/token/DerivedKeyToken.java b/src/org/apache/ws/security/message/token/DerivedKeyToken.java
new file mode 100755
index 0000000..08454de
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/DerivedKeyToken.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.ConversationException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ <DerivedKeyToken wsu:Id="..." wsc:Algorithm="...">
+ <SecurityTokenReference>...</SecurityTokenReference>
+ <Properties>...</Properties>
+ <Generation>...</Generation>
+ <Offset>...</Offset>
+ <Length>...</Length>
+ <Label>...</Label>
+ <Nonce>...</Nonce>
+ </DerivedKeyToken>
+ */
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+public class DerivedKeyToken {
+
+    private Log log = LogFactory.getLog(DerivedKeyToken.class.getName());
+
+    public static final QName TOKEN = new QName(ConversationConstants.WSC_NS,
+            ConversationConstants.
+            DERIVED_KEY_TOKEN_LN);
+
+    //These are the elements that are used to create the SecurityContextToken
+    protected Element element = null;
+    protected Element elementSecurityTokenReference = null;
+    protected Element elementProperties = null;
+    protected Element elementGeneration = null;
+    protected Element elementOffset = null;
+    protected Element elementLength = null;
+    protected Element elementLabel = null;
+    protected Element elementNonce = null;
+
+    /**
+     * This will create an empty DerivedKeyToken
+     *
+     * @param doc THe DOM document
+     */
+    public DerivedKeyToken(Document doc) {
+        log.debug("DerivedKeyToken: created");
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.
+                DERIVED_KEY_TOKEN_LN);
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+    }
+
+    /**
+     * This will create a DerivedKeyToken object with the given DErivedKeyToken element
+     *
+     * @param elem The DErivedKeyToken DOM element
+     * @throws WSSecurityException If the element is not a derived key token
+     */
+    public DerivedKeyToken(Element elem) throws WSSecurityException {
+        log.debug("DerivedKeyToken: created : element constructor");
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType00", new Object[]{el});
+        }
+        this.elementSecurityTokenReference = (Element) WSSecurityUtil.
+                getDirectChild(this.element,
+                        ConversationConstants.SECURITY_TOKEN_REFERENCE_LN,
+                        WSConstants.WSSE_NS);
+        this.elementProperties = (Element) WSSecurityUtil.getDirectChild(this.
+                element, ConversationConstants.PROPERTIES_LN,
+                ConversationConstants.WSC_NS);
+        this.elementGeneration = (Element) WSSecurityUtil.getDirectChild(this.
+                element, ConversationConstants.GENERATION_LN,
+                ConversationConstants.WSC_NS);
+        this.elementOffset = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.OFFSET_LN, ConversationConstants.WSC_NS);
+        this.elementLength = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.LENGTH_LN, ConversationConstants.WSC_NS);
+        this.elementLabel = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.LABEL_LN, ConversationConstants.WSC_NS);
+        this.elementNonce = (Element) WSSecurityUtil.getDirectChild(this.element,
+                ConversationConstants.NONCE_LN, ConversationConstants.WSC_NS);
+    }
+
+    /**
+     * Sets the security token reference of the derived key token
+     * This is the reference to the shared secret used in the conversation/context
+     *
+     * @param ref Security token reference
+     */
+    public void setSecuityTokenReference(SecurityTokenReference ref) {
+        this.elementSecurityTokenReference = ref.getElement();
+        //WSSecurityUtil.appendChildElement(doc, this.element, ref.getElement());
+        this.element.appendChild(ref.getElement());
+    }
+    
+    public void setSecuityTokenReference(Element elem) {
+        this.elementSecurityTokenReference = elem;
+        this.element.appendChild(elem);
+    }
+
+    /**
+     * Returns the SecurityTokenReference of the derived key token
+     *
+     * @return
+     * @throws WSSecurityException
+     */
+    public SecurityTokenReference getSecuityTokenReference() throws
+            WSSecurityException {
+        if (this.elementSecurityTokenReference != null) {
+            return new SecurityTokenReference(this.elementSecurityTokenReference);
+        }
+        return null;
+    }
+
+    //Write the getter for security token reference
+
+    /**
+     * This adds a property into
+     * /DerivedKeyToken/Properties
+     *
+     * @param propName  Name of the property
+     * @param propValue Value of the property
+     */
+    private void addProperty(String propName, String propValue) {
+        if (this.elementProperties == null) { //Create the properties element if it is not there
+            this.elementProperties = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" +
+                    ConversationConstants.PROPERTIES_LN);
+            WSSecurityUtil.setNamespace(this.elementProperties,
+                    ConversationConstants.WSC_NS,
+                    WSConstants.WSSE_PREFIX);
+            this.element.appendChild(this.elementProperties);
+        }
+        Element tempElement = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + propName);
+        tempElement.appendChild(this.element.getOwnerDocument().createTextNode(propValue));
+
+        this.elementProperties.appendChild(tempElement);
+    }
+
+    /**
+     * This is used to set the Name, Label and Nonce element values in the properties element
+     * <b>At this point I'm not sure if these are the only properties that will appear in the
+     * <code>Properties</code> element. There fore this method is provided
+     * If this is not required feel free to remove this :D
+     * </b>
+     *
+     * @param name  Value of the Properties/Name element
+     * @param label Value of the Properties/Label element
+     * @param nonce Value of the Properties/Nonce element
+     */
+    public void setProperties(String name, String label,
+                              String nonce) {
+        Hashtable table = new Hashtable(3);
+        table.put("Name", name);
+        table.put("Label", label);
+        table.put("Nonce", nonce);
+        this.setProperties(table);
+    }
+
+    /**
+     * If there are other types of properties other than Name, Label and Nonce
+     * This is provided for extensibility purposes
+     *
+     * @param properties The properties and values in a hashtable
+     */
+    public void setProperties(Hashtable properties) {
+        Enumeration keys = properties.keys();
+        while (keys.hasMoreElements()) {
+            String propertyName = (String) keys.nextElement(); //Get the property name
+            //Check whether this property is already there
+            //If so change the value
+            Node node = WSSecurityUtil.findElement(this.elementProperties,
+                    propertyName,
+                    ConversationConstants.WSC_NS);
+            if (node != null && node instanceof Element) { //If the node is not null
+                Text node1 = getFirstNode((Element) node);
+                node1.setData((String) properties.get(propertyName));
+            } else {
+                this.addProperty(propertyName,
+                        (String) properties.get(propertyName));
+            }
+        }
+    }
+
+    public Hashtable getProperties() {
+        if (this.elementProperties != null) {
+            Hashtable table = new Hashtable();
+            NodeList nodes = this.elementProperties.getChildNodes();
+            for (int i = 0; i < nodes.getLength(); i++) {
+                Node tempNode = nodes.item(i);
+                if (tempNode instanceof Element) {
+                    Text text = this.getFirstNode((Element) tempNode);
+                    table.put(tempNode.getNodeName(), text.getData());
+                }
+            }
+
+        }
+        return null;
+    }
+
+    /**
+     * Sets the length of the derived key
+     *
+     * @param length The length of the derived key as a long
+     */
+    public void setLength(int length) {
+        this.elementLength = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.LENGTH_LN);
+        WSSecurityUtil.setNamespace(this.elementLength,
+                ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementLength.appendChild(this.element.getOwnerDocument().createTextNode(Long.toString(length)));
+        this.element.appendChild(this.elementLength);
+    }
+
+    public int getLength() {
+        if (this.elementLength != null) {
+            return Integer.parseInt(getFirstNode(this.elementLength).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the offset
+     *
+     * @param offset The offset value as an integer
+     */
+    public void setOffset( int offset) throws ConversationException {
+        //This element MUST NOT be used if the <Generation> element is specified
+        if (this.elementGeneration == null) {
+            this.elementOffset = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" +
+                    ConversationConstants.OFFSET_LN);
+            WSSecurityUtil.setNamespace(this.elementOffset,
+                    ConversationConstants.WSC_NS,
+                    ConversationConstants.WSC_PREFIX);
+            this.elementOffset.appendChild(this.element.getOwnerDocument().createTextNode(Integer.toString(offset)));
+            this.element.appendChild(this.elementOffset);
+        } else {
+            throw new ConversationException("Offset cannot be set along with generation - generation is already set");
+        }
+
+    }
+
+    public int getOffset() {
+        if (this.elementOffset != null) {
+            return Integer.parseInt(getFirstNode(this.elementOffset).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the generation of the derived key
+     *
+     * @param generation generation value as an integer
+     */
+    public void setGeneration(int generation) throws
+            ConversationException {
+        //This element MUST NOT be used if the <Offset> element is specified
+        if (this.elementOffset == null) {
+            this.elementGeneration = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                    "wsc:" + ConversationConstants.GENERATION_LN);
+            WSSecurityUtil.setNamespace(this.elementGeneration,
+                    ConversationConstants.WSC_NS,
+                    ConversationConstants.WSC_PREFIX);
+            this.elementGeneration.appendChild(this.element.getOwnerDocument().createTextNode(Integer.toString(generation)));
+            this.element.appendChild(this.elementGeneration);
+        } else {
+            throw new ConversationException("Generatation cannot be set along with offset - Offset is already set");
+        }
+    }
+
+    public int getGeneration() {
+        if (this.elementGeneration != null) {
+            return Integer.parseInt(getFirstNode(this.elementGeneration).getData());
+        }
+        return -1;
+    }
+
+    /**
+     * Sets the label of the derived key
+     *
+     * @param label Label value as a string
+     */
+    public void setLabel(String label) {
+        this.elementLabel = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.LABEL_LN);
+        WSSecurityUtil.setNamespace(this.elementLabel, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementLabel.appendChild(this.element.getOwnerDocument().createTextNode(label));
+        this.element.appendChild(this.elementLabel);
+    }
+
+    /**
+     * Sets the nonce value of the derived key
+     *
+     * @param nonce Nonce value as a string
+     */
+    public void setNonce(String nonce) {
+        this.elementNonce = this.element.getOwnerDocument().createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" +
+                ConversationConstants.NONCE_LN);
+        WSSecurityUtil.setNamespace(this.elementNonce, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+        this.elementNonce.appendChild(this.element.getOwnerDocument().createTextNode(nonce));
+        this.element.appendChild(this.elementNonce);
+
+    }
+
+    /**
+     * Returns the label of the derived key token
+     *
+     * @return Label of the derived key token
+     */
+    public String getLabel() {
+        if (this.elementLabel != null) {
+            return getFirstNode(this.elementLabel).getData();
+        }
+        return null;
+    }
+
+    /**
+     * Return the nonce of the derived key token
+     *
+     * @return Nonce of the derived key token
+     */
+    public String getNonce() {
+        if (this.elementNonce != null) {
+            return getFirstNode(this.elementNonce).getData();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the first text node of an element.
+     *
+     * @param e the element to get the node from
+     * @return the first text node or <code>null</code> if node
+     *         is null or is not a text node
+     */
+    private Text getFirstNode(Element e) {
+        Node node = e.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * Returns the dom element of this <code>SecurityContextToken</code> object.
+     *
+     * @return the DerivedKeyToken element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     *
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Gets the id.
+     *
+     * @return the value of the <code>wsu:Id</code> attribute of this
+     *         DerivedKeyToken
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * Set the id of this derived key token.
+     *
+     * @param id the value for the <code>wsu:Id</code> attribute of this
+     *           DerivgedKeyToken
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+    /**
+     * Gets the derivattion algorithm
+     *
+     * @return the value of the <code>wsc:Algorithm</code> attribute of this
+     *         DerivedKeyToken
+     */
+    public String getAlgorithm() {
+        String algo = this.element.getAttributeNS(ConversationConstants.WSC_NS,
+                "Algorithm");
+        if (algo == null || algo.equals("")) {
+            return ConversationConstants.DerivationAlgorithm.P_SHA_1;
+        } else {
+            return algo;
+        }
+    }
+
+    /**
+     * Set the derivattion algorithm of this derived key token.
+     *
+     * @param derivattion algorithm the value for the <code>wsu:Algorithm</code> attribute of this
+     *                    DerivgedKeyToken
+     */
+    public void setAlgorithm(String algo) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                ConversationConstants.WSC_NS,
+                ConversationConstants.
+                WSC_PREFIX);
+        this.element.setAttributeNS(ConversationConstants.WSC_NS,
+                prefix + ":Algorithm", algo);
+    }
+
+}
diff --git a/src/org/apache/ws/security/message/token/PKIPathSecurity.java b/src/org/apache/ws/security/message/token/PKIPathSecurity.java
new file mode 100644
index 0000000..f6f50a2
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/PKIPathSecurity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * PKIPath Security Token.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class PKIPathSecurity extends BinarySecurity {
+    private static final String type = WSConstants.X509TOKEN_NS + "#X509PKIPathv1";
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @throws WSSecurityException
+     */
+    public PKIPathSecurity(Element elem)
+        throws WSSecurityException {
+        super(elem);
+        if (!getValueType().equals(getType())) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY_TOKEN,
+                "invalidValueType",
+                new Object[]{type, getValueType()});
+        }
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     */
+    public PKIPathSecurity(Document doc) {
+        super(doc);
+        setValueType(getType());
+    }
+
+    /**
+     * get the X509Certificate array.
+     * <p/>
+     *
+     * @param reverse
+     * @param crypto
+     * @return array of certifcates 
+     * @throws WSSecurityException
+     */
+    public X509Certificate[] getX509Certificates(boolean reverse, Crypto crypto)
+        throws WSSecurityException {
+        byte[] data = getToken();
+        if (data == null) {
+            return null;
+        }
+        X509Certificate[] certs = null;
+        certs = crypto.getX509Certificates(data, reverse);
+        return certs;
+    }
+
+    /**
+     * set the X509Certificate array.
+     * <p/>
+     *
+     * @param certs
+     * @param reverse
+     * @param crypto
+     * @throws WSSecurityException
+     */
+    public void setX509Certificates(X509Certificate[] certs,
+                                    boolean reverse,
+                                    Crypto crypto)
+        throws WSSecurityException {
+        if (certs == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "noCert");
+        }
+        byte[] data = crypto.getCertificateData(reverse, certs);
+        setToken(data);
+    }
+
+    public static String getType() {
+        return type;
+    }
+}
diff --git a/src/org/apache/ws/security/message/token/Reference.java b/src/org/apache/ws/security/message/token/Reference.java
new file mode 100644
index 0000000..5314085
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/Reference.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Reference.
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class Reference {
+    public static final QName TOKEN =
+        new QName(WSConstants.WSSE_NS, "Reference");
+    protected Element element = null;
+
+    /**
+     * Constructor.
+     * <p/>
+     * 
+     * @param elem 
+     * @throws WSSecurityException 
+     */
+    public Reference(Element elem) throws WSSecurityException {
+        if (elem == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY,
+                "noReference");
+        }
+        this.element = elem;
+        QName el =
+            new QName(
+                this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILURE,
+                "badElement",
+                new Object[] { TOKEN, el });
+        }
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     * 
+     * @param doc 
+     */
+    public Reference(Document doc) {
+        this.element =
+            doc.createElementNS(WSConstants.WSSE_NS, "wsse:Reference");
+        WSSecurityUtil.setNamespace(this.element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
+    }
+
+    /**
+     * get the dom element.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * get the URI.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String getValueType() {
+        return this.element.getAttribute("ValueType");
+    }
+
+    /**
+     * get the URI.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String getURI() {
+        return this.element.getAttribute("URI");
+    }
+
+    /**
+     * set the Value type.
+     * <p/>
+     * 
+     * @param valueType
+     */
+    public void setValueType(String valueType) {
+        this.element.setAttribute("ValueType", valueType);
+    }
+
+    /**
+     * set the URI.
+     * <p/>
+     * 
+     * @param uri 
+     */
+    public void setURI(String uri) {
+        this.element.setAttribute("URI", uri);
+    }
+
+    /**
+     * return the string representation.
+     * <p/>
+     * 
+     * @return TODO
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+}
diff --git a/src/org/apache/ws/security/message/token/SecurityContextToken.java b/src/org/apache/ws/security/message/token/SecurityContextToken.java
new file mode 100644
index 0000000..6ddf2ec
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/SecurityContextToken.java
@@ -0,0 +1,179 @@
+package org.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.UUIDGenerator;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+
+/**
+ * @author Ruchith Fernando
+ * @version 1.0
+ */
+public class SecurityContextToken {
+
+    public static final QName TOKEN = new QName(ConversationConstants.WSC_NS,
+            ConversationConstants.
+            SECURITY_CONTEXT_TOKEN_LN);
+
+    /**
+     * Security context token element
+     */
+    protected Element element = null;
+
+    /**
+     * Identifier element
+     */
+    protected Element elementIdentifier = null;
+
+    /**
+     * Constructor to create the SCT
+     *
+     * @param doc
+     */
+    public SecurityContextToken(Document doc) {
+
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+
+        this.elementIdentifier = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.IDENTIFIER_LN);
+
+        this.element.appendChild(this.elementIdentifier);
+
+        String uuid = UUIDGenerator.getUUID();
+        
+        this.elementIdentifier.appendChild(doc.createTextNode(uuid));
+        
+        this.setID("sctId-" + this.element.hashCode());
+    }
+
+    /**
+     * Constructor to create the SCT with a given uuid
+     *
+     * @param doc
+     */
+    public SecurityContextToken(Document doc, String uuid) {
+
+        this.element = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+
+        WSSecurityUtil.setNamespace(this.element, ConversationConstants.WSC_NS,
+                ConversationConstants.WSC_PREFIX);
+
+        this.elementIdentifier = doc.createElementNS(ConversationConstants.WSC_NS,
+                "wsc:" + ConversationConstants.IDENTIFIER_LN);
+
+        this.element.appendChild(this.elementIdentifier);
+
+        this.elementIdentifier.appendChild(doc.createTextNode(uuid));
+    }
+
+    /**
+     * This is used to create a SecurityContestToken using a DOM Element
+     *
+     * @param elem The DOM element: The security context token
+     * @throws WSSecurityException If the element passed in in not a security context token
+     */
+    public SecurityContextToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(),
+                this.element.getLocalName());
+        if (!el.equals(TOKEN)) {    // If the element is not a security context token
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN, "badTokenType00",
+                    new Object[]{el});
+        }
+        this.elementIdentifier = (Element) WSSecurityUtil.getDirectChild(element, ConversationConstants.IDENTIFIER_LN, ConversationConstants.WSC_NS);
+    }
+
+    /**
+     * Set the identifier.
+     *
+     * @param name sets a text node containing the identifier into
+     *             the identifier element.
+     */
+    public void setIdentifier(Document doc, String uuid) {
+        Text node = getFirstNode(this.elementIdentifier);
+        node.setData(uuid);
+    }
+
+    /**
+     * Get the identifier.
+     *
+     * @return the data from the identifier element.
+     */
+    public String getIdentifier() {
+        if (this.elementIdentifier != null) {
+            return getFirstNode(this.elementIdentifier).getData();
+        }
+        return null;
+    }
+
+    public void setElement(Element elem) {
+        this.element.appendChild(elem);
+    }
+
+    /**
+     * Returns the first text node of an element.
+     *
+     * @param e the element to get the node from
+     * @return the first text node or <code>null</code> if node
+     *         is null or is not a text node
+     */
+    private Text getFirstNode(Element e) {
+        Node node = e.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * Returns the dom element of this <code>SecurityContextToken</code> object.
+     *
+     * @return the <code>wsse:UsernameToken</code> element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     *
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Gets the id.
+     *
+     * @return the value of the <code>wsu:Id</code> attribute of this
+     *         SecurityContextToken
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * Set the id of this security context token.
+     *
+     * @param id the value for the <code>wsu:Id</code> attribute of this
+     *           SecurityContextToken
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+}
diff --git a/src/org/apache/ws/security/message/token/SecurityTokenReference.java b/src/org/apache/ws/security/message/token/SecurityTokenReference.java
new file mode 100644
index 0000000..32fa528
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/SecurityTokenReference.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.content.x509.XMLX509IssuerSerial;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.ws.security.util.Base64;
+import org.apache.xml.security.utils.Constants;
+import org.w3c.dom.*;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+/**
+ * Security Token Reference.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class SecurityTokenReference {
+    private static Log log =
+            LogFactory.getLog(SecurityTokenReference.class.getName());
+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");
+    public static final String SECURITY_TOKEN_REFERENCE = "SecurityTokenReference";
+    public static final String KEY_NAME = "KeyName";
+    public static final String SKI_URI = WSConstants.X509TOKEN_NS + "#X509SubjectKeyIdentifier";
+    public static final String THUMB_URI = WSConstants.SOAPMESSAGE_NS11 + "#" + WSConstants.THUMBPRINT;
+    public static final String SAML_ID_URI = WSConstants.SAMLTOKEN_NS + "#" + WSConstants.SAML_ASSERTION_ID;
+    protected Element element = null;
+    private XMLX509IssuerSerial issuerSerial = null;
+    private byte[] skiBytes = null;
+    
+    private static boolean doDebug = false;
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param elem TODO
+     * @throws WSSecurityException
+     */
+    public SecurityTokenReference(Element elem) throws WSSecurityException {
+        doDebug = log.isDebugEnabled();
+        this.element = elem;
+        boolean goodElement = false;
+        if (SECURITY_TOKEN_REFERENCE.equals(element.getLocalName())) {
+            goodElement = WSConstants.WSSE_NS.equals(element.getNamespaceURI());
+//        } else if (KEY_NAME.equals(element.getLocalName())) {
+//            goodElement = WSConstants.SIG_NS.equals(element.getNamespaceURI());
+        }
+        if (!goodElement) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "badElement",
+                    null);
+        }
+    }
+
+    /**
+     * Constructor.
+     * <p/>
+     *
+     * @param doc TODO
+     */
+    public SecurityTokenReference(Document doc) {
+        doDebug = log.isDebugEnabled();
+        this.element =
+                doc.createElementNS(WSConstants.WSSE_NS,
+                        "wsse:SecurityTokenReference");
+        WSSecurityUtil.setNamespace(this.element, WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);        
+    }
+
+    /*
+     * Here the methods that handle the direct reference inside
+     * a SecurityTokenReference
+     */
+
+    /**
+     * set the reference.
+     * <p/>
+     *
+     * @param ref
+     */
+    public void setReference(Reference ref) {
+        Element elem = getFirstElement();
+        if (elem != null) {
+            this.element.replaceChild(ref.getElement(), elem);
+        } else {
+            this.element.appendChild(ref.getElement());
+        }
+    }
+
+    /**
+     * Gets the Reference.
+     *
+     * @return the <code>Reference</code> element contained in this
+     *         SecurityTokeneReference
+     * @throws WSSecurityException
+     */
+    public Reference getReference() throws WSSecurityException {
+        Element elem = getFirstElement();
+        return new Reference(elem);
+    }
+
+    /**
+     * Gets the signing token element, which maybe a <code>BinarySecurityToken
+     * </code> or a SAML token.
+     * 
+     * The method gets the URI attribute of the {@link Reference} contained in
+     * the {@link SecurityTokenReference} and tries to find the referenced
+     * Element in the document.
+     *
+     * @param doc the document that contains the binary security token
+     *            element. This could be different from the document
+     *            that contains the SecurityTokenReference (STR). See
+     *            STRTransform.derefenceBST() method
+     * @return Element     containing the signing token, must be a BinarySecurityToken
+     * @throws WSSecurityException When either no <code>Reference</code> element, or the found
+     *                   reference contains no URI, or the referenced signing not found.
+     */
+    public Element getTokenElement(Document doc, WSDocInfo docInfo)
+            throws WSSecurityException {
+        Reference ref = getReference();
+        String uri = ref.getURI();
+        if (doDebug) {
+            log.debug("Token reference uri: " + uri);
+        }
+        if (uri == null) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                    "badReferenceURI");
+        }
+        Element tokElement = null;
+        String tmpS = WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION;
+        if (tmpS.equals(ref.getValueType())) {
+            Element sa = docInfo.getAssertion();
+            String saID = null;
+            if (sa != null) {
+                saID = sa.getAttribute("AssertionID");
+            }
+            if (doDebug) {
+                log.debug("SAML token ID: " + saID);
+            }
+            String id = uri.substring(1);
+            if (saID == null || !saID.equals(id)) {
+                throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                        "badReferenceURI",
+                        new Object[]{"uri:" + uri + ", saID: " + saID});
+            }
+            tokElement = sa;
+        } else {
+            tokElement = WSSecurityUtil.getElementByWsuId(doc, uri);
+        }
+        if (tokElement == null) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "noToken",
+                    new Object[]{uri});
+        }
+        return tokElement;
+    }
+
+    /*
+     * Here the methods that handle the various key identifer types
+     * such as KeyIdentifier, SubjectKeyIdentifier (SKI)
+     */
+
+    /**
+     * Sets the KeyIdentifer Element as a X509 certificate.
+     * Takes a X509 certificate, converts its data into base 64 and inserts
+     * it into a <code>wsse:KeyIdentifier</code> element, which is placed
+     * in the <code>wsse:SecurityTokenReference</code> element.
+     *
+     * @param cert is the X509 certficate to be inserted as key identifier
+     */
+    public void setKeyIdentifier(X509Certificate cert)
+            throws WSSecurityException {
+        Document doc = this.element.getOwnerDocument();
+        byte data[] = null;
+        try {
+            data = cert.getEncoded();
+        } catch (CertificateEncodingException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "encodeError");
+        }
+        Text text = doc.createTextNode(Base64.encode(data));
+        createKeyIdentifier(doc, X509Security.getType(), text);        
+    }
+
+    /**
+     * Sets the KeyIdentifer Element as a X509 Subject-Key-Identifier (SKI).
+     * Takes a X509 certificate, gets it SKI data, converts into base 64 and
+     * inserts it into a <code>wsse:KeyIdentifier</code> element, which is placed
+     * in the <code>wsse:SecurityTokenReference</code> element.
+     *
+     * @param cert   is the X509 certficate to get the SKI
+     * @param crypto is the Crypto implementation. Used to read SKI info bytes from certificate
+     */
+    public void setKeyIdentifierSKI(X509Certificate cert, Crypto crypto)
+            throws WSSecurityException {
+        Document doc = this.element.getOwnerDocument();
+        byte data[] = crypto.getSKIBytesFromCert(cert);
+        
+        org.w3c.dom.Text text = doc.createTextNode(Base64.encode(data));
+        createKeyIdentifier(doc, SKI_URI, text);        
+    }
+
+    /**
+     * Sets the KeyIdentifer Element as a Thumbprint.
+     * 
+     * Takes a X509 certificate, computes its thumbprint using SHA-1, converts
+     * into base 64 and inserts it into a <code>wsse:KeyIdentifier</code>
+     * element, which is placed in the <code>wsse:SecurityTokenReference</code>
+     * element.
+     * 
+     * @param cert
+     *            is the X509 certficate to get the thumbprint
+     */
+    public void setKeyIdentifierThumb(X509Certificate cert)
+            throws WSSecurityException {
+        Document doc = this.element.getOwnerDocument();
+        MessageDigest sha = null;
+        try {
+            sha = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e1) {
+            throw new WSSecurityException(0, "noSHA1availabe");
+        }
+        sha.reset();
+        try {
+            sha.update(cert.getEncoded());
+        } catch (CertificateEncodingException e1) {
+            throw new WSSecurityException(
+                    WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "encodeError");
+        }
+        byte[] data = sha.digest();
+
+        org.w3c.dom.Text text = doc.createTextNode(Base64.encode(data));
+        createKeyIdentifier(doc, THUMB_URI, text);
+    }
+    
+	public void setSAMLKeyIdentifier(String keyIdVal)
+			throws WSSecurityException {
+		Document doc = this.element.getOwnerDocument();
+        createKeyIdentifier(doc, SAML_ID_URI, doc.createTextNode(keyIdVal));
+	}
+
+    private void createKeyIdentifier(Document doc, String uri, Node node) {
+        
+        Element keyId = doc.createElementNS(WSConstants.WSSE_NS,
+                "wsse:KeyIdentifier");
+        keyId.setAttributeNS(null, "ValueType", uri);
+        keyId.setAttributeNS(null, "EncodingType",
+                BinarySecurity.BASE64_ENCODING);
+
+        keyId.appendChild(node);
+        Element elem = getFirstElement();
+        if (elem != null) {
+            this.element.replaceChild(keyId, elem);
+        } else {
+            this.element.appendChild(keyId);
+        }
+    }
+    /**
+     * Gets the KeyIdentifer.
+     *
+     * @return the the X509 certficate or zero if a unknown key identifier
+     *         type was detected.
+     */
+    public X509Certificate[] getKeyIdentifier(Crypto crypto)
+            throws WSSecurityException {
+        X509Security token = null;
+        Element elem = getFirstElement();
+        String value = elem.getAttribute("ValueType");
+        String alias = null;
+
+        if (X509Security.getType().equals(value)) {
+            token = new X509Security(elem);
+            if (token != null) {
+                X509Certificate cert = token.getX509Certificate(crypto);
+                X509Certificate[] certs = new X509Certificate[1];
+                certs[0] = cert;
+                return certs;
+            }
+        } else if (SKI_URI.equals(value)) {
+            alias = getX509SKIAlias(crypto);
+        } else if (THUMB_URI.equals(value)) {
+            Node node = getFirstElement().getFirstChild();
+            if (node == null) {
+                return null;
+            }
+            if (node.getNodeType() == Node.TEXT_NODE) {
+                byte[] thumb = Base64.decode(((Text) node).getData());
+                alias = crypto.getAliasForX509CertThumb(thumb);
+            }
+
+        }
+        if (alias != null) {
+            return crypto.getCertificates(alias);
+        }
+        return null;
+    }
+
+    public String getX509SKIAlias(Crypto crypto) throws WSSecurityException {
+        if (skiBytes == null) {
+            skiBytes = getSKIBytes();
+            if (skiBytes == null) {
+                return null;
+            }
+        }
+        String alias = crypto.getAliasForX509Cert(skiBytes);
+        if (doDebug) {
+            log.info("X509 SKI alias: " + alias);
+        }
+        return alias;
+    }
+
+    public byte[] getSKIBytes() {
+        if (skiBytes != null) {
+            return skiBytes;
+        }
+        Node node = getFirstElement().getFirstChild();
+        if (node == null) {
+            return null;
+        }
+        if (node.getNodeType() == Node.TEXT_NODE) {
+            try {
+                skiBytes = Base64.decode(((Text) node).getData());
+            } catch (WSSecurityException e) {
+                return null;
+            }
+        }
+        return skiBytes;
+    }
+
+    /*
+     * Here the methods that handle the IssuerSerial key identifiaton
+     */
+
+    /**
+     * Sets the X509 IssuerSerial data.
+     *
+     * @param ref the {@link XMLX509IssuerSerial} to put into this
+     *            SecurityTokenReference
+     */
+    public void setX509IssuerSerial(X509Data ref) {
+        Element elem = getFirstElement();
+        if (elem != null) {
+            this.element.replaceChild(ref.getElement(), elem);
+        } else {
+            this.element.appendChild(ref.getElement());
+        }
+    }
+
+    /**
+     * Gets the certificate identified with X509 issuerSerial data.
+     * This method first tries to get the embedded certificate.
+     * If this fails it checks if the certificate is  in the
+     * keystore.
+     *
+     * @return a certificate array or null if nothing found
+     */
+    public X509Certificate[] getX509IssuerSerial(Crypto crypto)
+            throws WSSecurityException {
+        String alias = getX509IssuerSerialAlias(crypto);
+        if (alias != null) {
+            return crypto.getCertificates(alias);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the alias name of the certificate identified with X509 issuerSerial data.
+     * The keystore identifies the certificate and the key with this alias name.
+     *
+     * @return the alias name for the certificate or null if nothing found
+     */
+    public String getX509IssuerSerialAlias(Crypto crypto)
+            throws WSSecurityException {
+        if (issuerSerial == null) {
+            issuerSerial = getIssuerSerial();
+            if (issuerSerial == null) {
+                return null;
+            }
+        }
+
+        String alias = crypto.getAliasForX509Cert(issuerSerial.getIssuerName(),
+                issuerSerial.getSerialNumber());
+
+        if (doDebug) {
+            log.info("X509IssuerSerial alias: " + alias);
+        }
+        return alias;
+    }
+
+    private XMLX509IssuerSerial getIssuerSerial() throws WSSecurityException {
+        if (issuerSerial != null) {
+            return issuerSerial;
+        }
+        Element elem = getFirstElement();
+        if (elem == null) {
+            return null;
+        }
+        try {
+            if (Constants._TAG_X509DATA.equals(elem.getLocalName())) {
+                elem = (Element)WSSecurityUtil.findElement(elem, Constants._TAG_X509ISSUERSERIAL, Constants.SignatureSpecNS);
+            }
+            issuerSerial = new XMLX509IssuerSerial(elem, "");
+        } catch (XMLSecurityException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "noToken",
+                    new Object[]{"Issuer/Serial data element missing"});
+        }
+        return issuerSerial;
+    }
+
+    /*
+     * Several helper and utility mehtods.
+     */
+
+    /**
+     * get the first child element.
+     *
+     * @return the first <code>Element</code> child node
+     */
+    public Element getFirstElement() {
+        for (Node currentChild = this.element.getFirstChild();
+             currentChild != null;
+             currentChild = currentChild.getNextSibling()) {
+            if (currentChild instanceof Element) {
+                return (Element) currentChild;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Method containsKeyName
+     *
+     * @return true if the <code>SecurtityTokenReference</code> contains
+     *         a <code>wsse:KeyName</code> element
+     */
+//    public boolean containsKeyName() {
+//        return element.getLocalName().equals(KEY_NAME);
+//    }
+//
+//    public String getKeyNameValue() {
+//        return element.getFirstChild().getNodeValue();
+//    }
+
+    /**
+     * Method containsReference
+     *
+     * @return true if the <code>SecurtityTokenReference</code> contains
+     *         a <code>wsse:Reference</code> element
+     */
+    public boolean containsReference() {
+        return this.lengthReference() > 0;
+    }
+
+    /**
+     * Method lengthReference.
+     *
+     * @return number of <code>wsse:Reference</code> elements in
+     *         the <code>SecurtityTokenReference</code>
+     */
+    public int lengthReference() {
+        return this.length(WSConstants.WSSE_NS, "Reference");
+    }
+
+    /**
+     * Method containsX509IssuerSerial
+     *
+     * @return true if the <code>SecurtityTokenReference</code> contains
+     *         a <code>ds:IssuerSerial</code> element
+     */
+    public boolean containsX509IssuerSerial() {
+        return this.lengthX509IssuerSerial() > 0;
+    }
+
+    /**
+     * Method containsX509Data
+     *
+     * @return true if the <code>SecurtityTokenReference</code> contains
+     *         a <code>ds:X509Data</code> element
+     */
+    public boolean containsX509Data() {
+        return this.lengthX509Data() > 0;
+    }
+    /**
+     * Method lengthX509IssuerSerial.
+     *
+     * @return number of <code>ds:IssuerSerial</code> elements in
+     *         the <code>SecurtityTokenReference</code>
+     */
+    public int lengthX509IssuerSerial() {
+        return this.length(WSConstants.SIG_NS, Constants._TAG_X509ISSUERSERIAL);
+    }
+
+    /**
+     * Method lengthX509Data.
+     *
+     * @return number of <code>ds:IssuerSerial</code> elements in
+     *         the <code>SecurtityTokenReference</code>
+     */
+    public int lengthX509Data() {
+        return this.length(WSConstants.SIG_NS, Constants._TAG_X509DATA);
+    }
+    /**
+     * Method containsKeyIdentifier.
+     *
+     * @return true if the <code>SecurtityTokenReference</code> contains
+     *         a <code>wsse:KeyIdentifier</code> element
+     */
+    public boolean containsKeyIdentifier() {
+        return this.lengthKeyIdentifier() > 0;
+    }
+
+    /**
+     * Method lengthKeyIdentifier.
+     *
+     * @return number of <code>wsse:KeyIdentifier</code> elements in
+     *         the <code>SecurtityTokenReference</code>
+     */
+    public int lengthKeyIdentifier() {
+        return this.length(WSConstants.WSSE_NS, "KeyIdentifier");
+    }
+
+    /**
+     * Method length.
+     *
+     * @param namespace
+     * @param localname
+     * @return number of elements with matching localname and namespace
+     */
+    public int length(String namespace, String localname) {
+        NodeList childNodes = this.element.getChildNodes();
+        int maxLength = childNodes.getLength();
+        int result = 0;
+        for (int i = 0; i < maxLength; i++) {
+            Node n = childNodes.item(i);
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                String ns = n.getNamespaceURI();
+                String name = n.getLocalName();
+                if (((namespace != null)
+                        && (ns != null)
+                        && namespace.equals(ns))
+                        || ((namespace == null) && (ns == null))) {
+                    if (localname.equals(name)) {
+                        result++;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * get the dom element.
+     * <p/>
+     *
+     * @return TODO
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * set the id.
+     * <p/>
+     *
+     * @param id
+     */
+    public void setID(String id) {
+        String prefix =
+                WSSecurityUtil.setNamespace(this.element,
+                        WSConstants.WSU_NS,
+                        WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+    /**
+     * return the string representation.
+     * <p/>
+     *
+     * @return TODO
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+}
diff --git a/src/org/apache/ws/security/message/token/SignatureConfirmation.java b/src/org/apache/ws/security/message/token/SignatureConfirmation.java
new file mode 100644
index 0000000..64402bf
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/SignatureConfirmation.java
@@ -0,0 +1,126 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.message.token;

+

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.util.DOM2Writer;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.ws.security.util.Base64;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+

+/**

+ * Signature Confirmation element.

+ *

+ *

+ * @author Werner Dittmann (Werner.Dittmann@t-online.de)

+ */

+public class SignatureConfirmation {

+

+    private static final String VALUE = "Value"; 

+    protected Element element = null;

+    private byte[] signatureValue = null;

+    /**

+     * Constructs a <code>SignatureConfirmation</code> object and parses the

+     * <code>wsse11:SignatureCOnfirmation</code> element to initialize it.

+     *

+     * @param elem the <code>wsse11:SignatureCOnfirmation</code> element that

+     *             contains the confirmation data

+     */

+    public SignatureConfirmation(Element elem) throws WSSecurityException {

+

+        element = elem;

+        String sv = element.getAttributeNS(null, VALUE);

+        if (sv != null) {

+            signatureValue = Base64.decode(sv);

+        }

+    }

+

+    /**

+     * Constructs a <code>SignatureConfirmation</code> object according

+     * to the defined parameters.

+     * <p/>

+     *

+     * @param doc the SOAP envelope as <code>Document</code>

+     * @param signVal the Signature value as byte[] of <code>null</code> 

+     *   if no value available.

+     */

+    public SignatureConfirmation(Document doc, byte[] signVal) {

+

+        element =

+                doc.createElementNS(WSConstants.WSSE11_NS,

+                        WSConstants.WSSE11_PREFIX

+                + ":"

+                + WSConstants.SIGNATURE_CONFIRMATION_LN);

+        WSSecurityUtil.setNamespace(element,

+                WSConstants.WSSE11_NS,

+                WSConstants.WSSE11_PREFIX);

+        if (signVal != null) {

+            String sv = Base64.encode(signVal);

+            element.setAttribute(VALUE, sv);

+        }

+

+    }

+

+    /**

+     * Returns the dom element of this <code>Timestamp</code> object.

+     *

+     * @return the <code>wsse:UsernameToken</code> element

+     */

+    public Element getElement() {

+        return this.element;

+    }

+

+    /**

+     * Returns the string representation of the token.

+     *

+     * @return a XML string representation

+     */

+    public String toString() {

+        return DOM2Writer.nodeToString((Node) this.element);

+    }

+    

+    /**

+     * Set wsu:Id attribute of this SignatureConfirmation element.

+     * @param id

+     */

+    public void setID(String id) {

+        String prefix = WSSecurityUtil.setNamespace(this.element,

+                WSConstants.WSU_NS, WSConstants.WSU_PREFIX);

+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);

+    }

+    

+    /**

+     * Returns the value of the wsu:Id attribute

+     * @return TODO

+     */

+    public String getID() {

+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");

+    }

+

+    /**

+     * @return Returns the signatureValue.

+     */

+    public byte[] getSignatureValue() {

+        return signatureValue;

+    }

+    

+}

diff --git a/src/org/apache/ws/security/message/token/Timestamp.java b/src/org/apache/ws/security/message/token/Timestamp.java
new file mode 100644
index 0000000..548233d
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/Timestamp.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.XmlSchemaDateFormat;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.Date;
+import java.util.Vector;
+
+/**
+ * Timestamp according to SOAP Message Security 1.0,
+ * chapter 10 / appendix A.2
+ * <p/>
+ *
+ * @author Christof Soehngen (christof.soehngen@syracom.de)
+ */
+public class Timestamp {
+
+    protected Element element = null;
+    protected Vector customElements = null;
+
+    protected Calendar created;
+    protected Calendar expires;
+    
+    /**
+     * Constructs a <code>Timestamp</code> object and parses the
+     * <code>wsu:Timestamp</code> element to initialize it.
+     *
+     * @param element the <code>wsu:Timestamp</code> element that
+     *             contains the timestamp data
+     */
+    public Timestamp(Element element) throws WSSecurityException {
+
+        this.element = element;
+        
+        customElements = new Vector();
+
+        String strCreated = null;
+        String strExpires = null;
+
+        for (Node currentChild = element.getFirstChild();
+             currentChild != null;
+             currentChild = currentChild.getNextSibling()) {
+            if (currentChild instanceof Element) {
+                if (WSConstants.CREATED_LN.equals(currentChild.getLocalName()) &&
+                        WSConstants.WSU_NS.equals(currentChild.getNamespaceURI())) {
+                	if (strCreated == null) {
+                		strCreated = ((Text) ((Element) currentChild).getFirstChild()).getData();
+                	}
+                	else {
+                        throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                                "invalidTimestamp");
+                	}
+                } else if (WSConstants.EXPIRES_LN.equals(currentChild.getLocalName()) &&
+                        WSConstants.WSU_NS.equals(currentChild.getNamespaceURI())) {
+                	if (strExpires == null) {
+                		strExpires = ((Text) ((Element) currentChild).getFirstChild()).getData();
+                	}
+                	else {
+                        throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                        "invalidTimestamp");                		
+                	}
+                } else {
+                    customElements.add((Element) currentChild);
+                }
+            }
+        }
+
+        DateFormat zulu = new XmlSchemaDateFormat();;
+        
+        try {
+        	if (strCreated != null) {
+                created = Calendar.getInstance();
+        		created.setTime(zulu.parse(strCreated));
+        	}
+        	if (strExpires != null) {
+                expires = Calendar.getInstance();
+        		expires.setTime(zulu.parse(strExpires));
+        	}
+        } catch (ParseException e) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
+                    "invalidTimestamp",
+                    null, e);
+        }
+    }
+
+
+    /**
+     * Constructs a <code>Timestamp</code> object according
+     * to the defined parameters.
+     * <p/>
+     *
+     * @param doc the SOAP envelope as <code>Document</code>
+     * @param ttl the time to live (validity of the security semantics) in seconds
+     */
+    public Timestamp(boolean milliseconds, Document doc, int ttl) {
+
+        customElements = new Vector();
+
+        element =
+                doc.createElementNS(WSConstants.WSU_NS,
+                        WSConstants.WSU_PREFIX
+                + ":"
+                + WSConstants.TIMESTAMP_TOKEN_LN);
+        WSSecurityUtil.setNamespace(element,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+
+        DateFormat zulu = null;
+        if (milliseconds) {
+        	zulu = new XmlSchemaDateFormat();
+        }
+        else {
+        	zulu = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        	zulu.setTimeZone(TimeZone.getTimeZone("UTC"));
+        }
+        created = getCurrentTime();
+
+        Element elementCreated =
+                doc.createElementNS(WSConstants.WSU_NS,
+                        WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN);
+        WSSecurityUtil.setNamespace(elementCreated,
+                WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        elementCreated.appendChild(doc.createTextNode(zulu.format(created.getTime())));
+        element.appendChild(elementCreated);
+        if (ttl != 0) {
+            long currentTime = created.getTimeInMillis();
+            currentTime += ttl * 1000;
+            expires = getCurrentTime();
+            expires.setTimeInMillis(currentTime);
+
+            Element elementExpires =
+                    doc.createElementNS(WSConstants.WSU_NS,
+                            WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN);
+            WSSecurityUtil.setNamespace(elementExpires,
+                    WSConstants.WSU_NS,
+                    WSConstants.WSU_PREFIX);
+            elementExpires.appendChild(doc.createTextNode(zulu.format(expires.getTime())));
+            element.appendChild(elementExpires);
+        }
+    }
+
+    /**
+     * Get the current time
+     * 
+     * @return calendar the current time
+     */
+    protected Calendar getCurrentTime() {
+    	return Calendar.getInstance();
+    }
+    
+    /**
+     * Returns the dom element of this <code>Timestamp</code> object.
+     *
+     * @return the <code>wsse:UsernameToken</code> element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     *
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Get the time of creation.
+     * <p/>
+     *
+     * @return the "created" time
+     */
+    public Calendar getCreated() {
+        return created;
+    }
+
+    /**
+     * Get the time of expiration.
+     * <p/>
+     *
+     * @return the "expires" time
+     */
+    public Calendar getExpires() {
+        return expires;
+    }
+
+    /**
+     * Creates and adds a custom element to this Timestamp
+     */
+    public void addCustomElement(Document doc, Element customElement) {
+        customElements.add(customElement);
+        element.appendChild(customElement);
+    }
+
+    /**
+     * Get the the custom elements from this Timestamp
+     *
+     * @return the vector containing the custom elements.
+     */
+    public Vector getCustomElements() {
+        return this.customElements;
+    }
+    
+    /**
+     * Set wsu:Id attribute of this timestamp
+     * @param id
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+    
+    /**
+     * Returns the value of the wsu:Id attribute
+     * @return TODO
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+    
+}
diff --git a/src/org/apache/ws/security/message/token/UsernameToken.java b/src/org/apache/ws/security/message/token/UsernameToken.java
new file mode 100644
index 0000000..4df8030
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/UsernameToken.java
@@ -0,0 +1,702 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.util.DOM2Writer;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.util.XmlSchemaDateFormat;
+import org.apache.ws.security.util.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.namespace.QName;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * UsernameToken according to WS Security specifications, UsernameToken profile.
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ */
+public class UsernameToken {
+    private static Log log = LogFactory.getLog(UsernameToken.class.getName());
+
+    public static final String PASSWORD_TYPE = "passwordType";
+
+    protected Element element = null;
+
+    protected Element elementUsername = null;
+
+    protected Element elementPassword = null;
+
+    protected Element elementNonce = null;
+
+    protected Element elementCreated = null;
+
+    protected Element elementSalt = null;
+
+    protected Element elementIteration = null;
+
+    protected String passwordType = null;
+
+    protected boolean hashed = true;
+
+    private static SecureRandom random = null;
+
+    private static int DEFAULT_ITERATION = 1000;
+
+    public static final QName TOKEN = new QName(WSConstants.WSSE_NS,
+            WSConstants.USERNAME_TOKEN_LN);
+
+    static {
+        try {
+            random = SecureRandom.getInstance("SHA1PRNG");
+        } catch (NoSuchAlgorithmException nsae) {
+            nsae.printStackTrace();
+        }
+    }
+
+    /**
+     * Constructs a <code>UsernameToken</code> object and parses the
+     * <code>wsse:UsernameToken</code> element to initialize it.
+     * 
+     * @param elem
+     *            the <code>wsse:UsernameToken</code> element that contains
+     *            the UsernameToken data
+     * @throws WSSecurityException
+     */
+    public UsernameToken(Element elem) throws WSSecurityException {
+        this.element = elem;
+        QName el = new QName(this.element.getNamespaceURI(), this.element
+                .getLocalName());
+        if (!el.equals(TOKEN)) {
+            throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType00", new Object[] { el });
+        }
+        elementUsername = (Element) WSSecurityUtil.getDirectChild(element,
+                "Username", WSConstants.WSSE_NS);
+        elementPassword = (Element) WSSecurityUtil.getDirectChild(element,
+                "Password", WSConstants.WSSE_NS);
+        elementNonce = (Element) WSSecurityUtil.getDirectChild(element,
+                "Nonce", WSConstants.WSSE_NS);
+        elementCreated = (Element) WSSecurityUtil.getDirectChild(element,
+                "Created", WSConstants.WSU_NS);
+        elementSalt = (Element) WSSecurityUtil.getDirectChild(element, "Salt",
+                WSConstants.WSSE11_NS);
+        elementIteration = (Element) WSSecurityUtil.getDirectChild(element,
+                "Interation", WSConstants.WSSE11_NS);
+        if (elementUsername == null) {
+            throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY_TOKEN,
+                    "badTokenType01", new Object[] { el });
+        }
+        if (elementSalt != null) {
+            if (elementPassword != null) {
+                throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY_TOKEN,
+                        "badTokenType01", new Object[] { el });
+            }
+            return;
+        }
+        hashed = false;
+        if (elementPassword != null) {
+            passwordType = elementPassword.getAttribute("Type");
+        }
+        if (passwordType != null
+                && passwordType.equals(WSConstants.PASSWORD_DIGEST)) {
+            hashed = true;
+            if (elementNonce == null || elementCreated == null) {
+                throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY_TOKEN,
+                        "badTokenType01", new Object[] { el });
+            }
+        }
+    }
+
+    /**
+     * Constructs a <code>UsernameToken</code> object according to the defined
+     * parameters. <p/> This constructes set the password encoding to
+     * {@link WSConstants#PASSWORD_DIGEST}
+     * 
+     * @param doc
+     *            the SOAP envelope as <code>Document</code>
+     */
+    public UsernameToken(boolean milliseconds, Document doc) {
+        this(milliseconds, doc, WSConstants.PASSWORD_DIGEST);
+    }
+
+    /**
+     * Constructs a <code>UsernameToken</code> object according to the defined
+     * parameters. <p/>
+     * 
+     * @param doc
+     *            the SOAP envelope as <code>Document</code>
+     * @param pwType
+     *            the required password encoding, either
+     *            {@link WSConstants#PASSWORD_DIGEST} or
+     *            {@link WSConstants#PASSWORD_TEXT} or <code>null</code> if no
+     *            password required
+     */
+    public UsernameToken(boolean milliseconds, Document doc, String pwType) {
+        this.element = doc.createElementNS(WSConstants.WSSE_NS, "wsse:"
+                + WSConstants.USERNAME_TOKEN_LN);
+        WSSecurityUtil.setNamespace(this.element, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        this.elementUsername = doc.createElementNS(WSConstants.WSSE_NS, "wsse:"
+                + WSConstants.USERNAME_LN);
+        WSSecurityUtil.setNamespace(this.elementUsername, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+        this.elementUsername.appendChild(doc.createTextNode(""));
+        element.appendChild(elementUsername);
+
+        if (pwType != null) {
+            this.elementPassword = doc.createElementNS(WSConstants.WSSE_NS,
+                    "wsse:" + WSConstants.PASSWORD_LN);
+            WSSecurityUtil.setNamespace(this.elementPassword,
+                    WSConstants.WSSE_NS, WSConstants.WSSE_PREFIX);
+            this.elementPassword.appendChild(doc.createTextNode(""));
+            element.appendChild(elementPassword);
+
+            hashed = false;
+            passwordType = pwType;
+            if (passwordType.equals(WSConstants.PASSWORD_DIGEST)) {
+                hashed = true;
+                addNonce(doc);
+                addCreated(milliseconds, doc);
+            }
+        }
+    }
+
+    /**
+     * Creates and adds a Nonce element to this UsernameToken
+     */
+    public void addNonce(Document doc) {
+        if (elementNonce != null) {
+            return;
+        }
+        byte[] nonceValue = new byte[16];
+        random.nextBytes(nonceValue);
+        this.elementNonce = doc.createElementNS(WSConstants.WSSE_NS, "wsse:"
+                + WSConstants.NONCE_LN);
+        WSSecurityUtil.setNamespace(this.elementNonce, WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+        this.elementNonce.appendChild(doc.createTextNode(Base64
+                .encode(nonceValue)));
+        element.appendChild(elementNonce);
+    }
+
+    /**
+     * Creates and adds a Created element to this UsernameToken
+     */
+    public void addCreated(boolean milliseconds, Document doc) {
+        if (elementCreated != null) {
+            return;
+        }
+        DateFormat zulu = null;
+        if (milliseconds) {
+            zulu = new XmlSchemaDateFormat();
+        } else {
+            zulu = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+            zulu.setTimeZone(TimeZone.getTimeZone("UTC"));
+        }
+        Calendar rightNow = Calendar.getInstance();
+        this.elementCreated = doc.createElementNS(WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN);
+        WSSecurityUtil.setNamespace(this.elementCreated, WSConstants.WSU_NS,
+                WSConstants.WSU_PREFIX);
+        this.elementCreated.appendChild(doc.createTextNode(zulu.format(rightNow
+                .getTime())));
+        element.appendChild(elementCreated);
+    }
+
+    /**
+     * Adds and otionally creates a Salt element to this UsernameToken.
+     * 
+     * If the <code>saltCalue</code> is <code>null</code> the the method
+     * generates a new salt. Otherwise it uses the the given value.
+     * 
+     * @param doc
+     *            The Document for the UsernameToken
+     * @param saltValue
+     *            The salt to add, if null generate a new salt value
+     * @param mac
+     *            If <code>true</code> then an optionally generated value is
+     *            usable for a MAC
+     * @return Returns the added salt
+     */
+    public byte[] addSalt(Document doc, byte[] saltValue, boolean mac) {
+
+        if (saltValue == null) {
+            saltValue = generateSalt(mac);
+        }
+        this.elementSalt = doc.createElementNS(WSConstants.WSSE11_NS,
+                WSConstants.WSSE11_PREFIX + WSConstants.SALT_LN);
+        WSSecurityUtil.setNamespace(this.elementSalt, WSConstants.WSSE11_NS,
+                WSConstants.WSSE11_PREFIX);
+        this.elementSalt.appendChild(doc.createTextNode(Base64
+                .encode(saltValue)));
+        element.appendChild(elementSalt);
+        return saltValue;
+    }
+
+    /**
+     * Creates and adds a Iteration element to this UsernameToken
+     */
+    public void addIteration(Document doc, int iteration) {
+        String text = "" + iteration;
+        this.elementIteration = doc.createElementNS(WSConstants.WSSE11_NS,
+                WSConstants.WSSE11_PREFIX + WSConstants.ITERATION_LN);
+        WSSecurityUtil.setNamespace(this.elementIteration,
+                WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX);
+        this.elementIteration.appendChild(doc.createTextNode(text));
+        element.appendChild(elementIteration);
+        return;
+    }
+
+    /**
+     * Get the user name.
+     * 
+     * @return the data from the user name element.
+     */
+    public String getName() {
+        return nodeString(this.elementUsername);
+    }
+
+    /**
+     * Set the user name.
+     * 
+     * @param name
+     *            sets a text node containing the use name into the user name
+     *            element.
+     */
+    public void setName(String name) {
+        Text node = getFirstNode(this.elementUsername);
+        node.setData(name);
+    }
+
+    /**
+     * Get the nonce.
+     * 
+     * @return the data from the nonce element.
+     */
+    public String getNonce() {
+        return nodeString(this.elementNonce);
+    }
+
+    /**
+     * Get the created timestamp.
+     * 
+     * @return the data from the created time element.
+     */
+    public String getCreated() {
+        return nodeString(this.elementCreated);
+    }
+
+    /**
+     * Gets the password string. This is the password as it is in the password
+     * element of a username, token. Thus it can be either plain text or the
+     * password digest value.
+     * 
+     * @return the password string or <code>null</code> if no such node
+     *         exists.
+     */
+    public String getPassword() {
+        return nodeString(this.elementPassword);
+    }
+
+    /**
+     * Get the Salt value of this UsernameToken.
+     * 
+     * @return Returns the binary Salt value or <code>null</code> if no Salt
+     *         value is available in the username token.
+     * @throws WSSecurityException
+     */
+    public byte[] getSalt() throws WSSecurityException {
+        String salt = nodeString(this.elementSalt);
+        if (salt != null) {
+            return Base64.decode(nodeString(this.elementSalt));
+        }
+        return null;
+    }
+
+    /**
+     * Get the Iteration value of this UsernameToken.
+     * 
+     * @return Returns the Iteration value. If no Iteration was specified in the
+     *         username token the default value according to the specification
+     *         is returned.
+     */
+    public int getIteration() {
+        String iter = nodeString(this.elementIteration);
+        if (iter != null) {
+            return Integer.parseInt(iter);
+        }
+        return DEFAULT_ITERATION;
+    }
+
+    /**
+     * Get the hashed inidicator. If the indicator is
+     * <code>true> the password of the
+     * <code>UsernameToken</code> was encoded using
+     * {@link WSConstants#PASSWORD_DIGEST}
+     *
+     * @return the hashed indicator.
+     */
+    public boolean isHashed() {
+        return hashed;
+    }
+
+    /**
+     * @return Returns the passwordType.
+     */
+    public String getPasswordType() {
+        return passwordType;
+    }
+
+    /**
+     * Sets the password string. This function sets the password in the
+     * <code>UsernameToken</code> either as plain text or encodes the password
+     * according to the WS Security specifications, UsernameToken profile, into
+     * a password digest.
+     * 
+     * @param pwd
+     *            the password to use
+     */
+    public void setPassword(String pwd) {
+        if (pwd == null) {
+            throw new IllegalArgumentException("pwd == null");
+        }
+        Text node = getFirstNode(this.elementPassword);
+        try {
+            if (!hashed) {
+                node.setData(pwd);
+                this.elementPassword.setAttribute("Type",
+                        WSConstants.PASSWORD_TEXT);
+            } else {
+                node.setData(doPasswordDigest(getNonce(), getCreated(), pwd));
+                this.elementPassword.setAttribute("Type",
+                        WSConstants.PASSWORD_DIGEST);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static String doPasswordDigest(String nonce, String created,
+            String password) {
+        String passwdDigest = null;
+        try {
+            byte[] b1 = Base64.decode(nonce);
+            byte[] b2 = created.getBytes("UTF-8");
+            byte[] b3 = password.getBytes("UTF-8");
+            byte[] b4 = new byte[b1.length + b2.length + b3.length];
+            int i = 0;
+            int offset = 0;
+            System.arraycopy(b1, 0, b4, offset, b1.length);
+            offset += b1.length;
+            
+            System.arraycopy(b2, 0, b4, offset, b2.length);
+            offset += b2.length;
+
+            System.arraycopy(b3, 0, b4, offset, b3.length);
+            
+            MessageDigest sha = MessageDigest.getInstance("SHA-1");
+            sha.reset();
+            sha.update(b4);
+            passwdDigest = Base64.encode(sha.digest());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return passwdDigest;
+    }
+
+    /**
+     * Returns the first text node of an element.
+     * 
+     * @param e
+     *            the element to get the node from
+     * @return the first text node or <code>null</code> if node is null or is
+     *         not a text node
+     */
+    private Text getFirstNode(Element e) {
+        Node node = e.getFirstChild();
+        return ((node != null) && node instanceof Text) ? (Text) node : null;
+    }
+
+    /**
+     * Returns the data of an elemen as String or null if either the the element
+     * does not contain a Text node or the node is empty.
+     * 
+     * @param e
+     *            DOM element
+     * @return Element text node data as String
+     */
+    private String nodeString(Element e) {
+        if (e != null) {
+            Text node = getFirstNode(e);
+            if (node != null) {
+                return node.getData();
+            }
+        }
+        return null;
+
+    }
+
+    /**
+     * Returns the dom element of this <code>UsernameToken</code> object.
+     * 
+     * @return the <code>wsse:UsernameToken</code> element
+     */
+    public Element getElement() {
+        return this.element;
+    }
+
+    /**
+     * Returns the string representation of the token.
+     * 
+     * @return a XML string representation
+     */
+    public String toString() {
+        return DOM2Writer.nodeToString((Node) this.element);
+    }
+
+    /**
+     * Gets the id.
+     * 
+     * @return the value of the <code>wsu:Id</code> attribute of this username
+     *         token
+     */
+    public String getID() {
+        return this.element.getAttributeNS(WSConstants.WSU_NS, "Id");
+    }
+
+    /**
+     * Set the id of this username token.
+     * 
+     * @param id
+     *            the value for the <code>wsu:Id</code> attribute of this
+     *            username token
+     */
+    public void setID(String id) {
+        String prefix = WSSecurityUtil.setNamespace(this.element,
+                WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
+        this.element.setAttributeNS(WSConstants.WSU_NS, prefix + ":Id", id);
+    }
+
+    /**
+     * Gets the secret key as per WS-Trust spec. This method uses default setting
+     * to generate the secret key. These default values are suitable for .NET
+     * WSE.
+     * 
+     * @return a secret key constructed from information conatined in this
+     *         username token
+     */
+    public byte[] getSecretKey() {
+        return getSecretKey(WSConstants.WSE_DERIVED_KEY_LEN,
+                WSConstants.LABEL_FOR_DERIVED_KEY);
+    }
+
+    /**
+     * Gets the secret key as per WS-Trust spec.
+     * 
+     * @param keylen
+     *            How many bytes to generate for the key
+     * @param labelString
+     *            the label used to generate the seed
+     * @return a secret key constructed from information conatined in this
+     *         username token
+     */
+    public byte[] getSecretKey(int keylen, String labelString) {
+        byte[] key = null;
+        try {
+            Mac mac = Mac.getInstance("HMACSHA1");
+            byte[] password = getPassword().getBytes("UTF-8");
+            byte[] label = labelString.getBytes("UTF-8");
+            byte[] nonce = Base64.decode(getNonce());
+            byte[] created = getCreated().getBytes("UTF-8");
+            byte[] seed = new byte[label.length + nonce.length + created.length];
+
+            int offset = 0;
+            System.arraycopy(label, 0, seed, offset, label.length);
+            offset += label.length;
+            
+            System.arraycopy(nonce, 0, seed, offset, nonce.length);
+            offset += nonce.length;
+
+            System.arraycopy(created, 0, seed, offset, created.length);
+            
+            key = P_hash(password, seed, mac, keylen);
+
+            if (log.isDebugEnabled()) {
+                log.debug("password   :" + Base64.encode(password));
+                log.debug("label      :" + Base64.encode(label));
+                log.debug("nonce      :" + Base64.encode(nonce));
+                log.debug("created    :" + Base64.encode(created));
+                log.debug("seed       :" + Base64.encode(seed));
+                log.debug("Key        :" + Base64.encode(key));
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return key;
+    }
+
+    /**
+     * This static method generates a derived key as defined in WSS Username
+     * Token Profile.
+     * 
+     * @param password
+     *            The password to include in the key generation
+     * @param salt
+     *            The Salt value
+     * @param iteration
+     *            The Iteration value. If zero (0) is given the mehtod uses the
+     *            default value
+     * @return Returns the derived key a byte array
+     * @throws WSSecurityException
+     */
+    public static byte[] generateDerivedKey(String password, byte[] salt,
+            int iteration) throws WSSecurityException {
+
+        if (iteration == 0) {
+            iteration = DEFAULT_ITERATION;
+        }
+        byte[] pwBytes = password.getBytes();
+
+        byte[] pwSalt = new byte[salt.length + pwBytes.length];
+        System.arraycopy(pwBytes, 0, pwSalt, 0, pwBytes.length);
+        System.arraycopy(salt, 0, pwSalt, pwBytes.length, salt.length);
+
+        MessageDigest sha = null;
+        try {
+            sha = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            throw new WSSecurityException(0, "noSHA1availabe");
+        }
+        sha.reset();
+
+        /*
+         * Make the first hash round with start value
+         */
+        byte[] K = sha.digest(pwSalt);
+        /*
+         * Perform the 2nd up to iteration hash rounds
+         */
+        for (int i = 2; i <= iteration; i++) {
+            sha.reset();
+            K = sha.digest(K);
+        }
+        return K;
+    }
+
+    /**
+     * This static method generates a 128 bit salt value as defined in WSS
+     * Username Token Profile.
+     * 
+     * @param useForMac
+     *            If <code>true</code> define the Salt for use in a MAC
+     * @return Returns the 128 bit salt value as byte array
+     */
+    public static byte[] generateSalt(boolean useForMac) {
+        byte[] saltValue = new byte[16];
+        random.nextBytes(saltValue);
+        if (useForMac) {
+            saltValue[15] = 0x01;
+        } else {
+            saltValue[15] = 0x02;
+        }
+        return saltValue;
+    }
+
+    /**
+     * P_hash as defined in RFC 2246 for TLS.
+     * 
+     * @param secret
+     *            is the key for the HMAC
+     * @param seed
+     *            the seed value to start the generation - A(0)
+     * @param mac
+     *            the HMAC algorithm
+     * @param required
+     *            number of bytes to generate
+     * @return a byte array that conatins a secrect key
+     * @throws Exception
+     */
+    private static byte[] P_hash(byte[] secret, byte[] seed, Mac mac,
+            int required) throws Exception {
+        byte[] out = new byte[required];
+        int offset = 0, tocpy;
+        byte[] A, tmp;
+        /*
+         * A(0) is the seed
+         */
+        A = seed;
+        SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
+        mac.init(key);
+        while (required > 0) {
+            mac.update(A);
+            A = mac.doFinal();
+            mac.update(A);
+            mac.update(seed);
+            tmp = mac.doFinal();
+            tocpy = min(required, tmp.length);
+            System.arraycopy(tmp, 0, out, offset, tocpy);
+            offset += tocpy;
+            required -= tocpy;
+        }
+        return out;
+    }
+
+    /*
+     * public static void main(String[] args) throws Exception { byte[] secret =
+     * Base64.decode("A4BKgeqUKi9VDwWyYPDrskwCwEQ5RIqH"); byte[] seed =
+     * Base64.decode("bWFzdGVyIHNlY3JldAAAAAAAAAAAAAAAAAAAAAAy+BE8DDEUf+XnAynZEVU0PUQR4QHesAbNCmt8/Ry6NqBELuBAiZV4Z0FuCT58Fi8=");
+     * int required = 48; Mac mac = Mac.getInstance("HMACSHA1"); byte[] out =
+     * UsernameToken.P_hash(secret, seed, mac, 48);
+     * System.out.println(Base64.encode(out));
+     * //UCbz0pT2DxRfx4IpY6iWRE0KCa4Fg9JKNRlrxE8AtjNjb1NEK17NI6XdrMRMOKM2 }
+     */
+
+    /**
+     * helper method.
+     * <p/>
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    private static int min(int a, int b) {
+        return (a > b) ? b : a;
+    }
+}
diff --git a/src/org/apache/ws/security/message/token/X509Security.java b/src/org/apache/ws/security/message/token/X509Security.java
new file mode 100644
index 0000000..d4be973
--- /dev/null
+++ b/src/org/apache/ws/security/message/token/X509Security.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.message.token;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+/**
+ * X509 Security Token.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class X509Security extends BinarySecurity {
+    private static final String type = WSConstants.X509TOKEN_NS + "#X509v3";
+    /*
+     * Stores the associated X.509 Certificate. This saves numerous
+     * crypto loadCertificate operations
+     */
+    private X509Certificate cachedCert = null;
+
+    /**
+     * This constructor creates a new X509 certificate object and initializes
+     * it from the data containe in the element.
+     *
+     * @param elem      the element containing the X509 certificate data
+     * @throws WSSecurityException
+     */
+    public X509Security(Element elem) throws WSSecurityException {
+        super(elem);
+        if (!getValueType().equals(type)) {
+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN, "invalidValueType", new Object[]{type, getValueType()});
+        }
+    }
+
+    /**
+     * This constructor creates a new X509 certificate element.
+     *
+     * @param doc
+     */
+    public X509Security(Document doc) {
+        super(doc);
+        setValueType(type);
+    }
+
+    /**
+     * Gets the X509Certificate certificate.
+     * <p/>
+     *
+     * @return the X509 certificate converted from the base 64 encoded
+     *         element data
+     * @throws WSSecurityException
+     */
+    public X509Certificate getX509Certificate(Crypto crypto) throws WSSecurityException {
+        if (cachedCert != null) {
+            return cachedCert;
+        }
+        byte[] data = getToken();
+        if (data == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "invalidCertData",
+                    new Object[]{new Integer(0)});
+        }
+        ByteArrayInputStream in = new ByteArrayInputStream(data);
+        cachedCert = crypto.loadCertificate(in);
+        return cachedCert;
+    }
+
+    /**
+     * Sets the X509Certificate.
+     * This functions takes the X509 certificate, gets the data from it as
+     * encoded bytes, and sets the data as base 64 encoded data in the text
+     * node of the element
+     *
+     * @param cert the X509 certificate to store in the element
+     * @throws WSSecurityException
+     */
+    public void setX509Certificate(X509Certificate cert)
+            throws WSSecurityException {
+        if (cert == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "noCert");
+        }
+        cachedCert = cert;
+        try {
+            setToken(cert.getEncoded());
+        } catch (CertificateEncodingException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                    "encodeError");
+        }
+    }
+
+    public static String getType() {
+        return type;
+    }
+}
diff --git a/src/org/apache/ws/security/policy/Constants.java b/src/org/apache/ws/security/policy/Constants.java
new file mode 100644
index 0000000..e87d9dd
--- /dev/null
+++ b/src/org/apache/ws/security/policy/Constants.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+public class Constants {
+
+    public final static String SP_NS = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy";
+    
+    public final static String ATTR_INCLUDE_TOKEN = "IncludeToken";
+
+    public final static String INCLUDE_NEVER = Constants.SP_NS
+            + "/IncludeToken/Never";
+
+    public final static String INCLUDE_ONCE = Constants.SP_NS
+            + "/IncludeToken/Once";
+
+    public final static String INCLUDE_ALWAYS_TO_RECIPIENT = Constants.SP_NS
+            + "/IncludeToken/AlwaysToRecipient";
+
+    public final static String INCLUDE_ALWAYS = Constants.SP_NS
+            + "/IncludeToken/Always";
+
+    
+    public final static int SUPPORTING_TOKEN_SUPPORTING = 1;
+    public final static int SUPPORTING_TOKEN_ENDORSING = 2;
+    public final static int SUPPORTING_TOKEN_SIGNED = 3;
+    public final static int SUPPORTING_TOKEN_SIGNED_ENDORSING = 4;
+    
+    /**
+     * Security Header Layout : Strict
+     */
+    public final static String LAYOUT_STRICT = "Strict";
+
+    /**
+     * Security Header Layout : Lax
+     */
+    public final static String LAYOUT_LAX = "Lax";
+
+    /**
+     * Security Header Layout : LaxTimestampFirst
+     */
+    public final static String LAYOUT_LAX_TIMESTAMP_FIRST = "LaxTimestampFirst";
+
+    /**
+     * Security Header Layout : LaxTimestampLast
+     */
+    public final static String LAYOUT_LAX_TIMESTAMP_LAST = "LaxTimestampLast";
+    
+    /**
+     * Protection Order : EncryptBeforeSigning
+     */
+    public final static String ENCRYPT_BEFORE_SIGNING = "EncryptBeforeSigning";
+
+    /**
+     * Protection Order : SignBeforeEncrypting
+     */
+    public final static String SIGN_BEFORE_ENCRYPTING = "SignBeforeEncrypting";
+    
+    public final static String WSS_X509_V1_TOKEN10 = "WssX509V1Token10";
+    
+    public final static String WSS_X509_V3_TOKEN10 = "WssX509V3Token10";
+    
+    public final static String WSS_X509_PKCS7_TOKEN10 = "WssX509Pkcs7Token10";
+    
+    public final static String WSS_X509_PKI_PATH_V1_TOKEN10 = 
+                                                    "WssX509PkiPathV1Token10";
+    
+    public final static String WSS_X509_V1_TOKEN11 = "WssX509V1Token11";
+    
+    public final static String WSS_X509_V3_TOKEN11 = "WssX509V3Token11";
+    
+    public final static String WSS_X509_PKCS7_TOKEN11 = "WssX509Pkcs7Token11";
+    
+    public final static String WSS_X509_PKI_PATH_V1_TOKEN11 = 
+                                                    "WssX509PkiPathV1Token11";
+    
+    ///
+    ///Algorithm Suites
+    ///
+    public final static String ALGO_SUITE_BASIC256 = "Basic256";
+    public final static String ALGO_SUITE_BASIC192 = "Basic192";
+    public final static String ALGO_SUITE_BASIC128 = "Basic128";
+    public final static String ALGO_SUITE_TRIPLE_DES = "TripleDes";
+    public final static String ALGO_SUITE_BASIC256_RSA15 = "Basic256Rsa15";
+    public final static String ALGO_SUITE_BASIC192_RSA15 = "Basic192Rsa15";
+    public final static String ALGO_SUITE_BASIC128_RSA15 = "Basic128Rsa15";
+    public final static String ALGO_SUITE_TRIPLE_DES_RSA15 = "TripleDesRsa15";
+    public final static String ALGO_SUITE_BASIC256_SHA256 = "Basic256Sha256";
+    public final static String ALGO_SUITE_BASIC192_SHA256 = "Basic192Sha256";
+    public final static String ALGO_SUITE_BASIC128_SHA256 = "Basic128Sha256";
+    public final static String ALGO_SUITE_TRIPLE_DES_SHA256 = "TripleDesSha256";
+    public final static String ALGO_SUITE_BASIC256_SHA256_RSA15 = 
+                                                        "Basic256Sha256Rsa15";
+    public final static String ALGO_SUITE_BASIC192_SHA256_RSA15 = 
+                                                        "Basic192Sha256Rsa15";
+    public final static String ALGO_SUITE_BASIC128_SHA256_RSA15 = 
+                                                        "Basic128Sha256Rsa15";
+    public final static String ALGO_SUITE_TRIPLE_DES_SHA256_RSA15 = 
+                                                        "TripleDesSha256Rsa15";
+    
+    ///
+    ///Algorithms
+    ///
+    public final static String HMAC_SHA1 = "http://www.w3.org/2000/09/xmldsig#hmac-sha1";
+
+    public final static String RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
+
+    public final static String SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1";
+
+    public final static String SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256";
+
+    public final static String SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512";
+
+    public final static String AES128 = "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
+
+    public final static String AES192 = "http://www.w3.org/2001/04/xmlenc#aes192-cbc";
+
+    public final static String AES256 = "http://www.w3.org/2001/04/xmlenc#aes256-cbc";
+
+    public final static String TRIPLE_DES = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc";
+
+    public final static String KW_AES128 = "http://www.w3.org/2001/04/xmlenc#kw-aes256";
+
+    public final static String KW_AES192 = "http://www.w3.org/2001/04/xmlenc#kw-aes192";
+
+    public final static String KW_AES256 = "http://www.w3.org/2001/04/xmlenc#kw-aes128";
+
+    public final static String KW_TRIPLE_DES = "http://www.w3.org/2001/04/xmlenc#kw-tripledes";
+
+    public final static String KW_RSA_OAEP = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p";
+
+    public final static String KW_RSA15 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5";
+
+    public final static String P_SHA1 = "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1";
+
+    public final static String P_SHA1_L128 = "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1";
+
+    public final static String P_SHA1_L192 = "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1";
+
+    public final static String P_SHA1_L256 = "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1";
+
+    public final static String XPATH = "http://www.w3.org/TR/1999/REC-xpath-19991116";
+
+    public final static String XPATH20 = "http://www.w3.org/2002/06/xmldsig-filter2";
+
+    public final static String C14N = "http://www.w3.org/2001/10/xml-c14n#";
+
+    public final static String EX_C14N = "http://www.w3.org/2001/10/xml-exc-c14n#";
+
+    public final static String SNT = "http://www.w3.org/TR/soap12-n11n";
+
+    public final static String STRT10 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform";
+}
diff --git a/src/org/apache/ws/security/policy/WSS4JConfig.java b/src/org/apache/ws/security/policy/WSS4JConfig.java
new file mode 100644
index 0000000..5d21711
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JConfig.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+//import org.apache.axis2.security.handler.config.InflowConfiguration;
+//import org.apache.axis2.security.handler.config.OutflowConfiguration;
+
+public class WSS4JConfig {
+
+//    private OutflowConfiguration outflowConfiguration;
+//    private InflowConfiguration inflowConfiguration;
+//    
+//    /**
+//     * @return Returns the inflowConfiguration.
+//     */
+//    public InflowConfiguration getInflowConfiguration() {
+//        return inflowConfiguration;
+//    }
+//    /**
+//     * @param inflowConfiguration The inflowConfiguration to set.
+//     */
+//    public void setInflowConfiguration(InflowConfiguration inflowConfiguration) {
+//        this.inflowConfiguration = inflowConfiguration;
+//    }
+//    /**
+//     * @return Returns the outflowConfiguration.
+//     */
+//    public OutflowConfiguration getOutflowConfiguration() {
+//        return outflowConfiguration;
+//    }
+//    /**
+//     * @param outflowConfiguration The outflowConfiguration to set.
+//     */
+//    public void setOutflowConfiguration(OutflowConfiguration outflowConfiguration) {
+//        this.outflowConfiguration = outflowConfiguration;
+//    }
+//    
+}
diff --git a/src/org/apache/ws/security/policy/WSS4JConfigBuilder.java b/src/org/apache/ws/security/policy/WSS4JConfigBuilder.java
new file mode 100644
index 0000000..82ae489
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JConfigBuilder.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.ws.security.policy.model.AsymmetricBinding;
+import org.apache.ws.security.policy.model.Binding;
+import org.apache.ws.security.policy.model.PolicyEngineData;
+import org.apache.ws.security.policy.model.SymmetricBinding;
+import org.apache.ws.security.policy.model.Wss10;
+import org.apache.ws.security.policy.model.Wss11;
+
+public class WSS4JConfigBuilder {
+    
+    public static void build(ArrayList topLevelPeds) throws WSSPolicyException {
+        Iterator topLevelPEDIterator = topLevelPeds.iterator();
+        WSS4JConfig config = new WSS4JConfig();
+        while (topLevelPEDIterator.hasNext()) {
+            PolicyEngineData ped = (PolicyEngineData) topLevelPEDIterator.next();
+            if(ped instanceof Binding) {
+                if(ped instanceof SymmetricBinding) {
+                    processSymmetricPolicyBinding((SymmetricBinding)ped, config);
+                } else {
+                    processAsymmetricPolicyBinding((AsymmetricBinding)ped, config);
+                }
+            } else if(ped instanceof Wss10) {
+                processWSS10((Wss10)ped, config);
+            } else if(ped instanceof Wss11) {
+                processWSS11((Wss11)ped, config);
+            }
+        }
+    }
+    
+
+    private static void processSymmetricPolicyBinding(SymmetricBinding symmbinding, WSS4JConfig config) {
+        //TODO
+        throw new UnsupportedOperationException("TODO");
+    }
+    
+    private static void processWSS10(Wss10 wss10, WSS4JConfig config) {
+        //TODO
+        throw new UnsupportedOperationException("TODO");
+    }
+    private static void processAsymmetricPolicyBinding(AsymmetricBinding binding, WSS4JConfig config) {
+        // TODO TODO
+        throw new UnsupportedOperationException("TODO");
+    }
+    
+    private static void processWSS11(Wss11 wss11, WSS4JConfig config) {
+       if(wss11.isRequireSignatureConfirmation()) {
+//           config.getInflowConfiguration().setEnableSignatureConfirmation(true);
+//           config.getOutflowConfiguration().setEnableSignatureConfirmation(true);
+       }
+    }
+    
+}
diff --git a/src/org/apache/ws/security/policy/WSS4JPolicyBuilder.java b/src/org/apache/ws/security/policy/WSS4JPolicyBuilder.java
new file mode 100644
index 0000000..2b1a49d
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JPolicyBuilder.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+/**
+ * @author Werner Dittmann (werner@apache.org)
+ */
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.ws.security.policy.model.AlgorithmSuite;
+import org.apache.ws.security.policy.model.AsymmetricBinding;
+import org.apache.ws.security.policy.model.Binding;
+import org.apache.ws.security.policy.model.Header;
+import org.apache.ws.security.policy.model.ProtectionToken;
+import org.apache.ws.security.policy.model.RecipientToken;
+import org.apache.ws.security.policy.model.InitiatorToken;
+import org.apache.ws.security.policy.model.EncryptionToken;
+import org.apache.ws.security.policy.model.SignatureToken;
+import org.apache.ws.security.policy.model.PolicyEngineData;
+import org.apache.ws.security.policy.model.SymmetricBinding;
+import org.apache.ws.security.policy.model.SymmetricAsymmetricBindingBase;
+import org.apache.ws.security.policy.model.SignedEncryptedElements;
+import org.apache.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.ws.security.policy.model.SupportingToken;
+import org.apache.ws.security.policy.model.Wss10;
+import org.apache.ws.security.policy.model.Wss11;
+
+public class WSS4JPolicyBuilder {
+
+    /**
+     * Compile the parsed security data into one Policy data block.
+     * 
+     * This methods loops over all top level Policy Engine data elements,
+     * extracts the parsed parameters and sets them into a single data block.
+     * During this processing the method prepares the parameters in a format
+     * that is ready for processing by the WSS4J functions.
+     * 
+     * <p/>
+     * 
+     * The WSS4J policy enabled handler takes this data block to control the
+     * setup of the security header.
+     * 
+     * @param topLevelPeds
+     *            The list of the top level Policy Engine data
+     * @return The compile Poilcy data block.
+     * @throws WSSPolicyException
+     */
+    public static WSS4JPolicyData build(ArrayList topLevelPeds)
+            throws WSSPolicyException {
+        Iterator topLevelPEDIterator = topLevelPeds.iterator();
+        WSS4JPolicyData wpd = new WSS4JPolicyData();
+        while (topLevelPEDIterator.hasNext()) {
+            PolicyEngineData ped = (PolicyEngineData) topLevelPEDIterator
+                    .next();
+            if (ped instanceof Binding) {
+                if (ped instanceof SymmetricBinding) {
+                    processSymmetricPolicyBinding((SymmetricBinding) ped, wpd);
+                } else {
+                    processAsymmetricPolicyBinding((AsymmetricBinding) ped, wpd);
+                }
+                /*
+                 * Don't change the order of Wss11 / Wss10 instance checks
+                 * because Wss11 extends Wss10 - thus first check Wss11.
+                 */
+            } else if (ped instanceof Wss11) {
+                processWSS11((Wss11) ped, wpd);
+            } else if (ped instanceof Wss10) {
+                processWSS10((Wss10) ped, wpd);
+            } else if (ped instanceof SignedEncryptedElements) {
+                processSignedEncryptedElements((SignedEncryptedElements) ped,
+                        wpd);
+            } else if (ped instanceof SignedEncryptedParts) {
+                processSignedEncryptedParts((SignedEncryptedParts) ped, wpd);
+            } else if (ped instanceof SupportingToken) {
+                processSupportingToken((SupportingToken) ped, wpd);
+            } else {
+                System.out.println("Unknown top level PED found: "
+                        + ped.getClass().getName());
+            }
+        }
+        return wpd;
+    }
+
+    /**
+     * Evaluate the symmetric policy binding data.
+     * 
+     * @param binding
+     *            The binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     * @throws WSSPolicyException
+     */
+    private static void processSymmetricPolicyBinding(
+            SymmetricBinding symmBinding, WSS4JPolicyData wpd)
+            throws WSSPolicyException {
+        wpd.setSymmetricBinding(true);
+        binding(symmBinding, wpd);
+        symmAsymmBinding(symmBinding, wpd);
+        symmetricBinding(symmBinding, wpd);
+    }
+
+    private static void processWSS10(Wss10 wss10, WSS4JPolicyData wpd) {
+        System.out
+                .println("Top level PED found: " + wss10.getClass().getName());
+        // TODO
+        // throw new UnsupportedOperationException("TODO");
+    }
+
+    /**
+     * Evaluate the asymmetric policy binding data.
+     * 
+     * @param binding
+     *            The binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     * @throws WSSPolicyException
+     */
+    private static void processAsymmetricPolicyBinding(
+            AsymmetricBinding binding, WSS4JPolicyData wpd)
+            throws WSSPolicyException {
+        wpd.setSymmetricBinding(false);
+        binding(binding, wpd);
+        symmAsymmBinding(binding, wpd);
+        asymmetricBinding(binding, wpd);
+    }
+
+    private static void processWSS11(Wss11 wss11, WSS4JPolicyData wpd) {
+        wpd.setSignatureConfirmation(wss11.isRequireSignatureConfirmation());
+    }
+
+    /**
+     * Populate elements to sign and/or encrypt with the message tokens.
+     * 
+     * @param sep
+     *            The data describing the elements (XPath)
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void processSignedEncryptedElements(
+            SignedEncryptedElements see, WSS4JPolicyData wpd) {
+        Iterator it = see.getXPathExpressions().iterator();
+        if (see.isSignedElements()) {
+            while (it.hasNext()) {
+                wpd.setSignedElements((String) it.next());
+            }
+        } else {
+            while (it.hasNext()) {
+                wpd.setEncryptedElements((String) it.next());
+            }
+        }
+    }
+
+    /**
+     * Populate parts to sign and/or encrypt with the message tokens.
+     * 
+     * @param sep
+     *            The data describing the parts
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void processSignedEncryptedParts(SignedEncryptedParts sep,
+            WSS4JPolicyData wpd) {
+        Iterator it = sep.getHeaders().iterator();
+        if (sep.isSignedParts()) {
+            wpd.setSignBody(sep.isBody());
+            while (it.hasNext()) {
+                Header header = (Header) it.next();
+                wpd.setSignedParts(header.getNamespace(), header.getName());
+            }
+        } else {
+            wpd.setEncryptBody(sep.isBody());
+            while (it.hasNext()) {
+                Header header = (Header) it.next();
+                wpd.setEncryptedParts(header.getNamespace(), header.getName());
+            }
+        }
+    }
+
+    /**
+     * Evaluate policy data that is common to all bindings.
+     * 
+     * @param binding
+     *            The common binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void binding(Binding binding, WSS4JPolicyData wpd) {
+        wpd.setLayout(binding.getLayout().getValue());
+        wpd.setIncludeTimestamp(binding.isIncludeTimestamp());
+    }
+
+    /**
+     * Evaluate policy data that is common to symmetric and asymmetric bindings.
+     * 
+     * @param binding
+     *            The symmetric/asymmetric binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void symmAsymmBinding(
+            SymmetricAsymmetricBindingBase binding, WSS4JPolicyData wpd) {
+        wpd.setEntireHeaderAndBodySignatures(binding
+                .isEntireHeaderAndBodySignatures());
+        wpd.setProtectionOrder(binding.getProtectionOrder());
+        wpd.setSignatureProtection(binding.isSignatureProtection());
+        wpd.setTokenProtection(binding.isTokenProtection());
+    }
+
+    /**
+     * Evaluate policy data that is specific to symmetric binding.
+     * 
+     * @param binding
+     *            The symmetric binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void symmetricBinding(SymmetricBinding binding,
+            WSS4JPolicyData wpd) throws WSSPolicyException {
+        PolicyEngineData ped = binding.getProtectionToken();
+        AlgorithmSuite suite = binding.getAlgorithmSuite();
+        if (ped != null) {
+            wpd.setProtectionToken(
+                    ((ProtectionToken) ped).getProtectionToken(), suite);
+        } else {
+            ped = binding.getEncryptionToken();
+            PolicyEngineData ped1 = binding.getSignatureToken();
+            if (ped == null && ped1 == null) {
+                // this is an error - throw something
+            }
+            wpd.setEncryptionToken(
+                    ((EncryptionToken) ped).getEncryptionToken(), suite);
+            wpd.setSignatureToken(((SignatureToken) ped).getSignatureToken(),
+                    suite);
+        }
+    }
+
+    /**
+     * Evaluate policy data that is specific to asymmetric binding.
+     * 
+     * @param binding
+     *            The asymmetric binding data
+     * @param wpd
+     *            The WSS4J data to initialize
+     */
+    private static void asymmetricBinding(AsymmetricBinding binding,
+            WSS4JPolicyData wpd) throws WSSPolicyException {
+        PolicyEngineData ped = binding.getRecipientToken();
+        PolicyEngineData ped1 = binding.getInitiatorToken();
+        if (ped == null && ped1 == null) {
+            // this is an error - throw something
+        }
+        AlgorithmSuite suite = binding.getAlgorithmSuite();
+        wpd
+                .setRecipientToken(((RecipientToken) ped).getRecipientToken(),
+                        suite);
+        wpd.setInitiatorToken(((InitiatorToken) ped1).getInitiatorToken(),
+                suite);
+    }
+
+    private static void processSupportingToken(SupportingToken token,
+            WSS4JPolicyData wpd) throws WSSPolicyException {
+        wpd.setSupportingToken(token);
+    }
+}
diff --git a/src/org/apache/ws/security/policy/WSS4JPolicyData.java b/src/org/apache/ws/security/policy/WSS4JPolicyData.java
new file mode 100644
index 0000000..2f3080f
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JPolicyData.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+/**
+ * @author Werner Dittmann (werner@apache.org)
+ */
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.policy.model.AlgorithmSuite;
+import org.apache.ws.security.policy.model.Header;
+import org.apache.ws.security.policy.model.SignedEncryptedElements;
+import org.apache.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.ws.security.policy.model.SupportingToken;
+import org.apache.ws.security.policy.model.Token;
+import org.apache.ws.security.policy.model.X509Token;
+
+public class WSS4JPolicyData {
+
+    /*
+     * Global settings for overall security processing
+     */
+    private boolean symmetricBinding;
+
+    private String layout;
+
+    private boolean includeTimestamp;
+
+    private boolean entireHeaderAndBodySignatures;
+
+    private String protectionOrder;
+
+    private boolean signatureProtection;
+
+    private boolean tokenProtection;
+
+    private boolean signatureConfirmation;
+
+    /*
+     * Message tokens for symmetrical binding
+     */
+    private WSS4JPolicyToken encryptionToken;
+
+    private WSS4JPolicyToken signatureToken;
+
+    /*
+     * Message tokens for asymmetrical binding
+     */
+    private WSS4JPolicyToken recipientToken; // used to encrypt data to
+
+    // receipient
+
+    private WSS4JPolicyToken initiatorToken; // used to sign data by
+
+    // initiator
+
+    /*
+     * Which parts or elements of the message to sign/encrypt with the messagen
+     * tokens. Parts or elements to sign/encrypt with supporting tokens are
+     * stored together with the tokens (see WSS4JPolicyToken).
+     */
+    private boolean signBody;
+
+    private boolean encryptBody;
+
+    private ArrayList signedParts;
+
+    private ArrayList signedElements;
+
+    private ArrayList encryptedParts;
+
+    private ArrayList encryptedElements;
+
+    /*
+     * Holds the supporting tokens elements
+     */
+    private WSS4JSupportingToken supportingToken;
+
+    private WSS4JSupportingToken signedSupportingToken;
+
+    private WSS4JSupportingToken endorsingSupportingToken;
+
+    private WSS4JSupportingToken signedEndorsingSupportingToken;
+
+    /**
+     * @return Returns the symmetricBinding.
+     */
+    public boolean isSymmetricBinding() {
+        return symmetricBinding;
+    }
+
+    /**
+     * @param symmetricBinding
+     *            The symmetricBinding to set.
+     */
+    public void setSymmetricBinding(boolean symmetricBinding) {
+        this.symmetricBinding = symmetricBinding;
+    }
+
+    /**
+     * @return Returns the entireHeaderAndBodySignatures.
+     */
+    public boolean isEntireHeaderAndBodySignatures() {
+        return entireHeaderAndBodySignatures;
+    }
+
+    /**
+     * @param entireHeaderAndBodySignatures
+     *            The entireHeaderAndBodySignatures to set.
+     */
+    public void setEntireHeaderAndBodySignatures(
+            boolean entireHeaderAndBodySignatures) {
+        this.entireHeaderAndBodySignatures = entireHeaderAndBodySignatures;
+    }
+
+    /**
+     * @return Returns the includeTimestamp.
+     */
+    public boolean isIncludeTimestamp() {
+        return includeTimestamp;
+    }
+
+    /**
+     * @param includeTimestamp
+     *            The includeTimestamp to set.
+     */
+    public void setIncludeTimestamp(boolean includeTimestamp) {
+        this.includeTimestamp = includeTimestamp;
+    }
+
+    /**
+     * @return Returns the layout.
+     */
+    public String getLayout() {
+        return layout;
+    }
+
+    /**
+     * @param layout
+     *            The layout to set.
+     */
+    public void setLayout(String layout) {
+        this.layout = layout;
+    }
+
+    /**
+     * @return Returns the protectionOrder.
+     */
+    public String getProtectionOrder() {
+        return protectionOrder;
+    }
+
+    /**
+     * @param protectionOrder
+     *            The protectionOrder to set.
+     */
+    public void setProtectionOrder(String protectionOrder) {
+        this.protectionOrder = protectionOrder;
+    }
+
+    /**
+     * @return Returns the signatureProtection.
+     */
+    public boolean isSignatureProtection() {
+        return signatureProtection;
+    }
+
+    /**
+     * @param signatureProtection
+     *            The signatureProtection to set.
+     */
+    public void setSignatureProtection(boolean signatureProtection) {
+        this.signatureProtection = signatureProtection;
+    }
+
+    /**
+     * @return Returns the tokenProtection.
+     */
+    public boolean isTokenProtection() {
+        return tokenProtection;
+    }
+
+    /**
+     * @param tokenProtection
+     *            The tokenProtection to set.
+     */
+    public void setTokenProtection(boolean tokenProtection) {
+        this.tokenProtection = tokenProtection;
+    }
+
+    /**
+     * @return Returns the signatureConfirmation.
+     */
+    public boolean isSignatureConfirmation() {
+        return signatureConfirmation;
+    }
+
+    /**
+     * @param signatureConfirmation
+     *            The signatureConfirmation to set.
+     */
+    public void setSignatureConfirmation(boolean signatureConfirmation) {
+        this.signatureConfirmation = signatureConfirmation;
+    }
+
+    /**
+     * Return the encryption token data.
+     * 
+     * The returned token data may be empty.
+     * 
+     * @return Returns the encryptionToken.
+     */
+    public WSS4JPolicyToken getEncryptionToken() {
+        if (encryptionToken == null) {
+            encryptionToken = new WSS4JPolicyToken();
+        }
+        return encryptionToken;
+    }
+
+    /**
+     * Sets the parameters for the encryption token according to parsed policy.
+     * 
+     * The encryption token is specific to the symmetric binding.
+     * 
+     * @param encryptionToken
+     *            The encryptionToken to set.
+     */
+    public void setEncryptionToken(Token encToken, AlgorithmSuite suite)
+            throws WSSPolicyException {
+        if (encToken instanceof X509Token) {
+            if (encryptionToken == null) {
+                encryptionToken = new WSS4JPolicyToken();
+            }
+            initializeWSS4JPolicyToken(encryptionToken, (X509Token) encToken,
+                    suite);
+        }
+    }
+
+    /**
+     * Sets the parameters for the protection token according to parsed policy.
+     * 
+     * The protection token is specific to the symmetric binding.
+     * 
+     * @param protectionToken
+     *            The protectionToken to set.
+     */
+    public void setProtectionToken(Token protectionToken, AlgorithmSuite suite)
+            throws WSSPolicyException {
+        setEncryptionToken(protectionToken, suite);
+        setSignatureToken(protectionToken, suite);
+    }
+
+    /**
+     * Return the signature token data.
+     * 
+     * The returned token data may be empty.
+     * 
+     * @return Returns the signatureToken.
+     */
+    public WSS4JPolicyToken getSignatureToken() {
+        if (signatureToken == null) {
+            signatureToken = new WSS4JPolicyToken();
+        }
+        return signatureToken;
+    }
+
+    /**
+     * Sets the parameters for the signature token according to parsed policy.
+     * 
+     * The signature token is specific to the symmetric binding.
+     * 
+     * @param signatureToken
+     *            The signatureToken to set.
+     */
+    public void setSignatureToken(Token sigToken, AlgorithmSuite suite)
+            throws WSSPolicyException {
+        if (sigToken instanceof X509Token) {
+            if (signatureToken == null) {
+                signatureToken = new WSS4JPolicyToken();
+            }
+            initializeWSS4JPolicyToken(signatureToken, (X509Token) sigToken,
+                    suite);
+        }
+    }
+
+    /**
+     * Return the initiator token data.
+     * 
+     * The returned token data may be empty.
+     * 
+     * @return Returns the initiatorToken.
+     */
+    public WSS4JPolicyToken getInitiatorToken() {
+        if (initiatorToken == null) {
+            initiatorToken = new WSS4JPolicyToken();
+        }
+        return initiatorToken;
+    }
+
+    /**
+     * Sets the parameters for the initiator token according to parsed policy.
+     * 
+     * The initiator token is specific to the symmetric binding. The message
+     * initiator uses this token to sign its data. Thus this method initializes
+     * the signature relevant parts of the WSS4JPolicyToken data.
+     * 
+     * @param initiatorToken
+     *            The initiatorToken to set.
+     */
+    public void setInitiatorToken(Token iniToken, AlgorithmSuite suite)
+            throws WSSPolicyException {
+        if (iniToken instanceof X509Token) {
+            if (initiatorToken == null) {
+                initiatorToken = new WSS4JPolicyToken();
+            }
+            initializeWSS4JPolicyToken(initiatorToken, (X509Token) iniToken,
+                    suite);
+        }
+    }
+
+    /**
+     * Return the recipient token data.
+     * 
+     * The returned token data may be empty.
+     * 
+     * @return Returns the recipientToken.
+     */
+    public WSS4JPolicyToken getRecipientToken() {
+        if (recipientToken == null) {
+            recipientToken = new WSS4JPolicyToken();
+        }
+        return recipientToken;
+    }
+
+    /**
+     * Sets the parameters for the initiator token according to parsed policy.
+     * 
+     * The initiator token is specific to the symmetric binding. The message
+     * initiator uses this token to encrypt data sent to the reipient. Thus this
+     * method initializes the encryption relevant parts of the WSS4JPolicyToken
+     * data.
+     * 
+     * @param recipientToken
+     *            The recipientToken to set.
+     */
+    public void setRecipientToken(Token recToken, AlgorithmSuite suite)
+            throws WSSPolicyException {
+        if (recToken instanceof X509Token) {
+            if (recipientToken == null) {
+                recipientToken = new WSS4JPolicyToken();
+            }
+            initializeWSS4JPolicyToken(recipientToken, (X509Token) recToken,
+                    suite);
+        }
+    }
+
+    /**
+     * @return Returns the encryptedElements.
+     */
+    public ArrayList getEncryptedElements() {
+        return encryptedElements;
+    }
+
+    /**
+     * @param encElement
+     *            The encrypted Element (XPath) to set.
+     */
+    public void setEncryptedElements(String encElement) {
+        if (encryptedElements == null) {
+            encryptedElements = new ArrayList();
+        }
+        encryptedElements.add(encElement);
+    }
+
+    /**
+     * @return Returns the encryptedParts.
+     */
+    public ArrayList getEncryptedParts() {
+        return encryptedParts;
+    }
+
+    /**
+     * @param namespace
+     *            The namespace of the part.
+     * @param element
+     *            The part's element name.
+     */
+    public void setEncryptedParts(String namespace, String element) {
+        if (encryptedParts == null) {
+            encryptedParts = new ArrayList();
+        }
+        WSEncryptionPart wep = new WSEncryptionPart(element, namespace,
+                "Content");
+        encryptedParts.add(wep);
+    }
+
+    /**
+     * @return Returns the encryptBody.
+     */
+    public boolean isEncryptBody() {
+        return encryptBody;
+    }
+
+    /**
+     * @param encryptBody
+     *            The encryptBody to set.
+     */
+    public void setEncryptBody(boolean encryptBody) {
+        this.encryptBody = encryptBody;
+    }
+
+    /**
+     * @return Returns the signBody.
+     */
+    public boolean isSignBody() {
+        return signBody;
+    }
+
+    /**
+     * @param signBody
+     *            The signBody to set.
+     */
+    public void setSignBody(boolean signBody) {
+        this.signBody = signBody;
+    }
+
+    /**
+     * @return Returns the signedElements.
+     */
+    public ArrayList getSignedElements() {
+        return signedElements;
+    }
+
+    /**
+     * @param sigElement
+     *            The signed Element (XPath) to set.
+     */
+    public void setSignedElements(String sigElement) {
+        if (signedElements == null) {
+            signedElements = new ArrayList();
+        }
+        signedElements.add(sigElement);
+    }
+
+    /**
+     * @return Returns the signedParts.
+     */
+    public ArrayList getSignedParts() {
+        return signedParts;
+    }
+
+    /**
+     * @param namespace
+     *            The namespace of the part.
+     * @param element
+     *            The part's element name.
+     */
+    public void setSignedParts(String namespace, String element) {
+        if (signedParts == null) {
+            signedParts = new ArrayList();
+        }
+        WSEncryptionPart wep = new WSEncryptionPart(element, namespace,
+                "Content");
+        signedParts.add(wep);
+    }
+
+    public void setSupportingToken(SupportingToken suppToken)
+            throws WSSPolicyException {
+
+        Iterator it = null;
+        WSS4JSupportingToken wst = new WSS4JSupportingToken();
+
+        /*
+         * Get and store the parts to sign of the supporting token
+         */
+        SignedEncryptedParts sep = suppToken.getSignedParts();
+        if (sep != null) {
+            it = sep.getHeaders().iterator();
+            if (wst.sigParts == null) {
+                wst.sigParts = new ArrayList();
+            }
+            while (it.hasNext()) {
+                Header header = (Header) it.next();
+                wst.sigParts.add(new WSEncryptionPart(header.getName(), header
+                        .getNamespace(), "Content"));
+            }
+        }
+        /*
+         * Get and store the parts to encrypt of the supporting token
+         */
+        sep = suppToken.getEncryptedParts();
+        if (sep != null) {
+            it = sep.getHeaders().iterator();
+            if (wst.encParts == null) {
+                wst.encParts = new ArrayList();
+            }
+            while (it.hasNext()) {
+                Header header = (Header) it.next();
+                wst.encParts.add(new WSEncryptionPart(header.getName(), header
+                        .getNamespace(), "Content"));
+            }
+        }
+
+        /*
+         * Get and store the elements (XPath) to sign of the supporting token
+         */
+        SignedEncryptedElements see = suppToken.getSignedElements();
+        if (see != null) {
+            it = see.getXPathExpressions().iterator();
+            if (wst.sigElements == null) {
+                wst.sigElements = new ArrayList();
+            }
+            while (it.hasNext()) {
+                wst.sigElements.add((String) it.next());
+            }
+        }
+        /*
+         * Get and store the elements (XPath) to encrypt of the supporting token
+         */
+        see = suppToken.getEncryptedElements();
+        if (see != null) {
+            it = see.getXPathExpressions().iterator();
+            if (wst.encElements == null) {
+                wst.encElements = new ArrayList();
+            }
+            while (it.hasNext()) {
+                wst.encElements.add((String) it.next());
+            }
+        }
+        AlgorithmSuite suite = suppToken.getAlgorithmSuite();
+
+        /*
+         * Iterator over all tokens, initialize their data structure, and store
+         * them in the support token data structure.
+         */
+        it = suppToken.getToken().iterator();
+        while (it.hasNext()) {
+            if (wst.supportTokens == null) {
+                wst.supportTokens = new ArrayList();
+            }
+
+            Token tok = (Token) it.next();
+            if (tok instanceof X509Token) {
+                WSS4JPolicyToken wpt = new WSS4JPolicyToken();
+                wst.supportTokens.add(wpt);
+                initializeWSS4JPolicyToken(wpt, (X509Token) tok, suite);
+            }
+        }
+        /*
+         * The supporting token is parsed and initialized, set it according to
+         * its type.
+         */
+        wst.tokenType = suppToken.getType();
+        if (wst.tokenType == Constants.SUPPORTING_TOKEN_SUPPORTING) {
+            supportingToken = wst;
+        } else if (wst.tokenType == Constants.SUPPORTING_TOKEN_SIGNED) {
+            signedSupportingToken = wst;
+        } else if (wst.tokenType == Constants.SUPPORTING_TOKEN_ENDORSING) {
+            endorsingSupportingToken = wst;
+        } else if (wst.tokenType == Constants.SUPPORTING_TOKEN_SIGNED_ENDORSING) {
+            signedEndorsingSupportingToken = wst;
+        }
+    }
+
+    private static void initializeWSS4JPolicyToken(WSS4JPolicyToken tok,
+            X509Token x509Tok, AlgorithmSuite suite) throws WSSPolicyException {
+        tok.tokenType = WSS4JPolicyToken.X509Token;
+        tok.encAlgorithm = suite.getEncryption();
+        tok.sigAlgorithm = suite.getAsymmetricSignature();
+        tok.encTransportAlgorithm = suite.getAsymmetricKeyWrap();
+        if (x509Tok.isRequireIssuerSerialReference()) {
+            tok.keyIdentifier = WSConstants.ISSUER_SERIAL;
+        } else if (x509Tok.isRequireThumbprintReference()) {
+            tok.keyIdentifier = WSConstants.THUMBPRINT_IDENTIFIER;
+        } else if (x509Tok.isRequireEmbeddedTokenReference()) {
+            tok.keyIdentifier = WSConstants.BST_DIRECT_REFERENCE;
+        } else {
+            throw new WSSPolicyException(
+                    "Unknown key reference specifier for X509Token");
+
+        }
+    }
+
+}
diff --git a/src/org/apache/ws/security/policy/WSS4JPolicyToken.java b/src/org/apache/ws/security/policy/WSS4JPolicyToken.java
new file mode 100644
index 0000000..296be1a
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JPolicyToken.java
@@ -0,0 +1,118 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy;

+

+import java.util.ArrayList;

+

+/**

+ * 

+ * This class holds data and parameters for a specific token. The

+ * signedParts/Elements and encryptedParts/Elements lists hold additional

+ * information in case of supporting tokens.

+ * 

+ * <p/>

+ * 

+ * The data is not declared as private to provide direct access from

+ * other classes in this package.

+ * 

+ * @author Werner Dittmann (werner@apache.org)

+ */

+public class WSS4JPolicyToken {

+	

+	public static int X509Token = 1;

+	

+	int tokenType;

+	

+	String sigAlgorithm;

+

+	int keyIdentifier;

+

+	String encAlgorithm;

+

+	String encTransportAlgorithm;

+

+	ArrayList sigParts;

+

+	ArrayList sigElements;

+

+	ArrayList encParts;

+

+	ArrayList encElements;

+

+	/**

+	 * @return Returns the tokenType.

+	 */

+	public int getTokenType() {

+		return tokenType;

+	}

+

+	/**

+	 * @return Returns the encAlgorithm.

+	 */

+	public String getEncAlgorithm() {

+		return encAlgorithm;

+	}

+

+	/**

+	 * @return Returns the encElements.

+	 */

+	public ArrayList getEncElements() {

+		return encElements;

+	}

+

+	/**

+	 * @return Returns the encKeyIdentifier.

+	 */

+	public int getKeyIdentifier() {

+		return keyIdentifier;

+	}

+

+	/**

+	 * @return Returns the encParts.

+	 */

+	public ArrayList getEncParts() {

+		return encParts;

+	}

+

+	/**

+	 * @return Returns the encTransportAlgorithm.

+	 */

+	public String getEncTransportAlgorithm() {

+		return encTransportAlgorithm;

+	}

+

+	/**

+	 * @return Returns the sigAlgorithm.

+	 */

+	public String getSigAlgorithm() {

+		return sigAlgorithm;

+	}

+

+	/**

+	 * @return Returns the sigElements.

+	 */

+	public ArrayList getSigElements() {

+		return sigElements;

+	}

+

+	/**

+	 * @return Returns the sigParts.

+	 */

+	public ArrayList getSigParts() {

+		return sigParts;

+	}

+}

diff --git a/src/org/apache/ws/security/policy/WSS4JSupportingToken.java b/src/org/apache/ws/security/policy/WSS4JSupportingToken.java
new file mode 100644
index 0000000..ff37902
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSS4JSupportingToken.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+import java.util.ArrayList;
+
+/**
+ * 
+ * This class holds data and parameters for a supporting token. 
+ * 
+ * The data is not declared as private to provide direct access from
+ * other classes in this package.
+ * 
+ * @author Werner Dittmann (werner@apache.org)
+ */
+
+public class WSS4JSupportingToken {
+    int tokenType;
+    
+    ArrayList supportTokens;
+    
+    ArrayList sigParts;
+
+    ArrayList sigElements;
+
+    ArrayList encParts;
+
+    ArrayList encElements;
+}
diff --git a/src/org/apache/ws/security/policy/WSSPolicyException.java b/src/org/apache/ws/security/policy/WSSPolicyException.java
new file mode 100644
index 0000000..8c534f7
--- /dev/null
+++ b/src/org/apache/ws/security/policy/WSSPolicyException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy;
+
+public class WSSPolicyException extends Exception {
+
+    private static final long serialVersionUID = 5904800255533588133L;
+
+    public WSSPolicyException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    public WSSPolicyException(String message) {
+        super(message);
+    }
+
+}
diff --git a/src/org/apache/ws/security/policy/model/AlgorithmSuite.java b/src/org/apache/ws/security/policy/model/AlgorithmSuite.java
new file mode 100644
index 0000000..0661059
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/AlgorithmSuite.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class AlgorithmSuite extends PolicyEngineData {
+    
+    private String symmetricSignature = Constants.HMAC_SHA1;
+    
+    private String asymmetricSignature = Constants.RSA_SHA1;
+
+    private String computedKey = Constants.P_SHA1;
+
+    private int maximumSymmetricKeyLength = 256;
+    
+    private int minimumAsymmetricKeyLength = 1024;
+    
+    private int maximumAsymmetricKeyLength = 4096;
+
+    private String digest;
+    
+    private String encryption;
+    
+    private String symmetricKeyWrap;
+    
+    private String asymmetricKeyWrap;
+    
+    private String encryptionKeyDerivation;
+    
+    private String signatureKeyDerivation;
+    
+    private int minimumSymmetricKeyLength;
+    
+    private String c14n = Constants.EX_C14N;
+    
+    private String soapNormalization;
+
+    private String strTransform;
+    
+    private String xPath;
+    
+//    public AlgorithmSuite (String algoSuite) throws WSSPolicyException {
+//        this.setAlgorithmSuite(algoSuite);
+//    }
+    
+    /**
+     * Set the algorithm suite
+     * @param algoSuite
+     * @throws WSSPolicyException
+     * @see Constants#ALGO_SUITE_BASIC128
+     * @see Constants#ALGO_SUITE_BASIC128_RSA15
+     * @see Constants#ALGO_SUITE_BASIC128_SHA256
+     * @see Constants#ALGO_SUITE_BASIC128_SHA256_RSA15
+     * @see Constants#ALGO_SUITE_BASIC192
+     * @see Constants#ALGO_SUITE_BASIC192_RSA15
+     * @see Constants#ALGO_SUITE_BASIC192_SHA256
+     * @see Constants#ALGO_SUITE_BASIC192_SHA256_RSA15
+     * @see Constants#ALGO_SUITE_BASIC256
+     * @see Constants#ALGO_SUITE_BASIC256_RSA15
+     * @see Constants#ALGO_SUITE_BASIC256_SHA256
+     * @see Constants#ALGO_SUITE_BASIC256_SHA256_RSA15
+     * @see Constants#ALGO_SUITE_TRIPLE_DES
+     * @see Constants#ALGO_SUITE_TRIPLE_DES_RSA15
+     * @see Constants#ALGO_SUITE_TRIPLE_DES_SHA256
+     * @see Constants#ALGO_SUITE_TRIPLE_DES_SHA256_RSA15
+     */
+    public void setAlgorithmSuite(String algoSuite) throws WSSPolicyException {
+        //TODO: Optimize this :-)
+        if(Constants.ALGO_SUITE_BASIC256.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES256;
+            this.symmetricKeyWrap = Constants.KW_AES256;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L256;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 256;
+        } else if (Constants.ALGO_SUITE_BASIC192.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES192;
+            this.symmetricKeyWrap = Constants.KW_AES192;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if (Constants.ALGO_SUITE_BASIC128.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES128;
+            this.symmetricKeyWrap = Constants.KW_AES128;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L128;
+            this.signatureKeyDerivation = Constants.P_SHA1_L128;
+            this.minimumSymmetricKeyLength = 128;
+        } else if(Constants.ALGO_SUITE_TRIPLE_DES.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.TRIPLE_DES;
+            this.symmetricKeyWrap = Constants.KW_TRIPLE_DES;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if (Constants.ALGO_SUITE_BASIC256_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES256;
+            this.symmetricKeyWrap = Constants.KW_AES256;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L256;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 256;
+        } else if (Constants.ALGO_SUITE_BASIC192_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES192;
+            this.symmetricKeyWrap = Constants.KW_AES192;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if (Constants.ALGO_SUITE_BASIC128_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.AES128;
+            this.symmetricKeyWrap = Constants.KW_AES128;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L128;
+            this.signatureKeyDerivation = Constants.P_SHA1_L128;
+            this.minimumSymmetricKeyLength = 128;
+        } else if (Constants.ALGO_SUITE_TRIPLE_DES_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA1;
+            this.encryption = Constants.TRIPLE_DES;
+            this.symmetricKeyWrap = Constants.KW_TRIPLE_DES;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if(Constants.ALGO_SUITE_BASIC256_SHA256.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES256;
+            this.symmetricKeyWrap = Constants.KW_AES256;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L256;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 256;
+        } else if (Constants.ALGO_SUITE_BASIC192_SHA256.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES192;
+            this.symmetricKeyWrap = Constants.KW_AES192;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if (Constants.ALGO_SUITE_BASIC128_SHA256.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES128;
+            this.symmetricKeyWrap = Constants.KW_AES128;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L128;
+            this.signatureKeyDerivation = Constants.P_SHA1_L128;
+            this.minimumSymmetricKeyLength = 128;
+        } else if(Constants.ALGO_SUITE_TRIPLE_DES_SHA256.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.TRIPLE_DES;
+            this.symmetricKeyWrap = Constants.KW_TRIPLE_DES;
+            this.asymmetricKeyWrap = Constants.KW_RSA_OAEP;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        }  else if (Constants.ALGO_SUITE_BASIC256_SHA256_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES256;
+            this.symmetricKeyWrap = Constants.KW_AES256;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L256;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 256;
+        } else if (Constants.ALGO_SUITE_BASIC192_SHA256_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES192;
+            this.symmetricKeyWrap = Constants.KW_AES192;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else if (Constants.ALGO_SUITE_BASIC128_SHA256_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.AES128;
+            this.symmetricKeyWrap = Constants.KW_AES128;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L128;
+            this.signatureKeyDerivation = Constants.P_SHA1_L128;
+            this.minimumSymmetricKeyLength = 128;
+        } else if (Constants.ALGO_SUITE_TRIPLE_DES_SHA256_RSA15.equals(algoSuite)) {
+            this.digest = Constants.SHA256;
+            this.encryption = Constants.TRIPLE_DES;
+            this.symmetricKeyWrap = Constants.KW_TRIPLE_DES;
+            this.asymmetricKeyWrap = Constants.KW_RSA15;
+            this.encryptionKeyDerivation = Constants.P_SHA1_L192;
+            this.signatureKeyDerivation = Constants.P_SHA1_L192;
+            this.minimumSymmetricKeyLength = 192;
+        } else {
+            throw new WSSPolicyException("Invalid algorithm suite : " + algoSuite);
+        }
+    }
+
+    /**
+     * @return Returns the asymmetricKeyWrap.
+     */
+    public String getAsymmetricKeyWrap() {
+        return asymmetricKeyWrap;
+    }
+
+    /**
+     * @return Returns the asymmetricSignature.
+     */
+    public String getAsymmetricSignature() {
+        return asymmetricSignature;
+    }
+
+    /**
+     * @return Returns the computedKey.
+     */
+    public String getComputedKey() {
+        return computedKey;
+    }
+
+    /**
+     * @return Returns the digest.
+     */
+    public String getDigest() {
+        return digest;
+    }
+
+    /**
+     * @return Returns the encryption.
+     */
+    public String getEncryption() {
+        return encryption;
+    }
+
+    /**
+     * @return Returns the encryptionKeyDerivation.
+     */
+    public String getEncryptionKeyDerivation() {
+        return encryptionKeyDerivation;
+    }
+
+    /**
+     * @return Returns the maximumAsymmetricKeyLength.
+     */
+    public int getMaximumAsymmetricKeyLength() {
+        return maximumAsymmetricKeyLength;
+    }
+
+    /**
+     * @return Returns the maximumSymmetricKeyLength.
+     */
+    public int getMaximumSymmetricKeyLength() {
+        return maximumSymmetricKeyLength;
+    }
+
+    /**
+     * @return Returns the minimumAsymmetricKeyLength.
+     */
+    public int getMinimumAsymmetricKeyLength() {
+        return minimumAsymmetricKeyLength;
+    }
+
+    /**
+     * @return Returns the minimumSymmetricKeyLength.
+     */
+    public int getMinimumSymmetricKeyLength() {
+        return minimumSymmetricKeyLength;
+    }
+
+    /**
+     * @return Returns the signatureKeyDerivation.
+     */
+    public String getSignatureKeyDerivation() {
+        return signatureKeyDerivation;
+    }
+
+    /**
+     * @return Returns the symmetricKeyWrap.
+     */
+    public String getSymmetricKeyWrap() {
+        return symmetricKeyWrap;
+    }
+
+    /**
+     * @return Returns the symmetricSignature.
+     */
+    public String getSymmetricSignature() {
+        return symmetricSignature;
+    }
+
+    /**
+     * @return Returns the c14n.
+     */
+    public String getInclusiveC14n() {
+        return c14n;
+    }
+
+    /**
+     * @param c14n The c14n to set.
+     */
+    public void setC14n(String c14n) throws WSSPolicyException {
+            this.c14n = c14n;
+    }
+
+    /**
+     * @return Returns the soapNormalization.
+     */
+    public String getSoapNormalization() {
+        return soapNormalization;
+    }
+
+    /**
+     * @param soapNormalization The soapNormalization to set.
+     */
+    public void setSoapNormalization(String soapNormalization) throws WSSPolicyException {
+            this.soapNormalization = soapNormalization;
+    }
+
+    /**
+     * @return Returns the strTransform.
+     */
+    public String getStrTransform() {
+        return strTransform;
+    }
+
+    /**
+     * @param strTransform The strTransform to set.
+     */
+    public void setStrTransform(String strTransform) throws WSSPolicyException {
+            this.strTransform = strTransform;
+    }
+
+    /**
+     * @return Returns the xPath.
+     */
+    public String getXPath() {
+        return xPath;
+    }
+
+    /**
+     * @param path The xPath to set.
+     */
+    public void setXPath(String path) throws WSSPolicyException{
+        xPath = path;
+    }
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/AlgorithmWrapper.java b/src/org/apache/ws/security/policy/model/AlgorithmWrapper.java
new file mode 100644
index 0000000..e1efcc3
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/AlgorithmWrapper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public interface AlgorithmWrapper {
+
+    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) throws WSSPolicyException;
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/AsymmetricBinding.java b/src/org/apache/ws/security/policy/model/AsymmetricBinding.java
new file mode 100644
index 0000000..27dc82d
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/AsymmetricBinding.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class AsymmetricBinding extends SymmetricAsymmetricBindingBase {
+    
+    private InitiatorToken initiatorToken;
+    
+    private RecipientToken recipientToken;
+    
+    /**
+     * @return Returns the initiatorToken.
+     */
+    public InitiatorToken getInitiatorToken() {
+        return initiatorToken;
+    }
+    /**
+     * @param initiatorToken The initiatorToken to set.
+     */
+    public void setInitiatorToken(InitiatorToken initiatorToken) {
+        this.initiatorToken = initiatorToken;
+    }
+    /**
+     * @return Returns the recipientToken.
+     */
+    public RecipientToken getRecipientToken() {
+        return recipientToken;
+    }
+    /**
+     * @param recipientToken The recipientToken to set.
+     */
+    public void setRecipientToken(RecipientToken recipientToken) {
+        this.recipientToken = recipientToken;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Binding.java b/src/org/apache/ws/security/policy/model/Binding.java
new file mode 100644
index 0000000..6081bcc
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Binding.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class Binding extends PolicyEngineData implements AlgorithmWrapper {
+
+    private AlgorithmSuite algorithmSuite;
+    private boolean includeTimestamp;
+    private Layout layout = new Layout();
+    
+    /**
+     * @return Returns the algorithmSuite.
+     */
+    public AlgorithmSuite getAlgorithmSuite() {
+        return algorithmSuite;
+    }
+
+    /**
+     * @param algorithmSuite The algorithmSuite to set.
+     */
+    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
+        this.algorithmSuite = algorithmSuite;
+    }
+
+    /**
+     * @return Returns the includeTimestamp.
+     */
+    public boolean isIncludeTimestamp() {
+        return includeTimestamp;
+    }
+
+    /**
+     * @param includeTimestamp The includeTimestamp to set.
+     */
+    public void setIncludeTimestamp(boolean includeTimestamp) {
+        this.includeTimestamp = includeTimestamp;
+    }
+    
+    /**
+     * @return Returns the layout.
+     */
+    public Layout getLayout() {
+        return layout;
+    }
+
+    /**
+     * @param layout The layout to set.
+     */
+    public void setLayout(Layout layout) throws WSSPolicyException {
+        this.layout = layout;
+    }
+}
diff --git a/src/org/apache/ws/security/policy/model/EncryptionToken.java b/src/org/apache/ws/security/policy/model/EncryptionToken.java
new file mode 100644
index 0000000..68c8db0
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/EncryptionToken.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class EncryptionToken extends PolicyEngineData implements TokenWrapper {
+
+    private Token encryptionToken;
+
+    /**
+     * @return Returns the encryptionToken.
+     */
+    public Token getEncryptionToken() {
+        return encryptionToken;
+    }
+
+    /**
+     * @param encryptionToken The encryptionToken to set.
+     */
+    public void setEncryptionToken(Token encryptionToken) {
+        this.encryptionToken = encryptionToken;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.policy.TokenWrapper#setToken(org.apache.ws.security.policy.Token)
+     */
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.setEncryptionToken(tok);
+    }
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Header.java b/src/org/apache/ws/security/policy/model/Header.java
new file mode 100644
index 0000000..836cd80
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Header.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class Header extends PolicyEngineData {
+
+    private String name;
+    private String namespace;
+    
+    /**
+     * @return Returns the name.
+     */
+    public String getName() {
+        return name;
+    }
+    /**
+     * @param name The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+    /**
+     * @return Returns the namespace.
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+    /**
+     * @param namespace The namespace to set.
+     */
+    public void setNamespace(String namespace) {
+        this.namespace = namespace;
+    }
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/InitiatorToken.java b/src/org/apache/ws/security/policy/model/InitiatorToken.java
new file mode 100644
index 0000000..2c651dd
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/InitiatorToken.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class InitiatorToken extends PolicyEngineData implements TokenWrapper {
+    
+    private Token initiatorToken;
+
+    /**
+     * @return Returns the initiatorToken.
+     */
+    public Token getInitiatorToken() {
+        return initiatorToken;
+    }
+
+    /**
+     * @param initiatorToken The initiatorToken to set.
+     */
+    public void setInitiatorToken(Token initiatorToken) {
+        this.initiatorToken = initiatorToken;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.policy.TokenWrapper#setToken(org.apache.ws.security.policy.Token)
+     */
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.setInitiatorToken(tok);
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Layout.java b/src/org/apache/ws/security/policy/model/Layout.java
new file mode 100644
index 0000000..98851c1
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Layout.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class Layout extends PolicyEngineData {
+   
+    private String value = Constants.LAYOUT_LAX;
+
+    /**
+     * @return Returns the value.
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * @param value The value to set.
+     */
+    public void setValue(String value) throws WSSPolicyException{
+        if(Constants.LAYOUT_LAX.equals(value) ||
+                Constants.LAYOUT_STRICT.equals(value) ||
+                Constants.LAYOUT_LAX_TIMESTAMP_FIRST.equals(value) ||
+                Constants.LAYOUT_LAX_TIMESTAMP_LAST.equals(value)) {
+                 this.value = value;
+             } else {
+                 throw new WSSPolicyException("Incorrect layout value : " + value);
+             }
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/PolicyEngineData.java b/src/org/apache/ws/security/policy/model/PolicyEngineData.java
new file mode 100644
index 0000000..7c965c2
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/PolicyEngineData.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import javax.xml.namespace.QName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSSPolicyException;
+import org.apache.ws.security.policy.parser.SecurityPolicy;
+
+public class PolicyEngineData {
+
+    private static Log log = LogFactory.getLog(PolicyEngineData.class);
+    
+    public void initializeWithDefaults() {
+        
+    }
+    
+    public static  PolicyEngineData copy(QName name) throws WSSPolicyException {
+        if(name.getLocalPart().equals(SecurityPolicy.symmetricBinding.getTokenName())) {
+            return new SymmetricBinding();
+        } else if (name.getLocalPart().equals(SecurityPolicy.asymmetricBinding.getTokenName())) {
+            return new AsymmetricBinding();
+        } else if (name.getLocalPart().equals(SecurityPolicy.transportBinding.getTokenName())) {
+            return new TransportBinding();
+        } else if (name.getLocalPart().equals(SecurityPolicy.algorithmSuite.getTokenName())) {
+            return new AlgorithmSuite();
+        } else if (name.getLocalPart().equals(SecurityPolicy.signedElements.getTokenName())) {
+            return new SignedEncryptedElements(true);
+        } else if (name.getLocalPart().equals(SecurityPolicy.encryptedElements.getTokenName())) {
+            return new SignedEncryptedElements(false);
+        } else if (name.getLocalPart().equals(SecurityPolicy.signedParts.getTokenName())) {
+            return new SignedEncryptedParts(true);
+        } else if (name.getLocalPart().equals(SecurityPolicy.encryptedParts.getTokenName())) {
+            return new SignedEncryptedParts(false);
+        } else if (name.getLocalPart().equals(SecurityPolicy.header.getTokenName())) {
+            return new Header();
+        } else if (name.getLocalPart().equals(SecurityPolicy.protectionToken.getTokenName())) {
+            return new ProtectionToken();
+        } else if (name.getLocalPart().equals(SecurityPolicy.signatureToken.getTokenName())) {
+            return new SignatureToken();
+        } else if (name.getLocalPart().equals(SecurityPolicy.encryptionToken.getTokenName())) {
+            return new EncryptionToken();
+        } else if (name.getLocalPart().equals(SecurityPolicy.x509Token.getTokenName())) {
+            return new X509Token();
+        } else if (name.getLocalPart().equals(SecurityPolicy.layout.getTokenName())) {
+            return new Layout();
+        } else if (name.getLocalPart().equals(SecurityPolicy.signedSupportingTokens.getTokenName())) {
+            return new SupportingToken(Constants.SUPPORTING_TOKEN_SIGNED);
+        } else if (name.getLocalPart().equals(SecurityPolicy.signedEndorsingSupportingTokens.getTokenName())) {
+            return new SupportingToken(Constants.SUPPORTING_TOKEN_SIGNED_ENDORSING);
+        } else if (name.getLocalPart().equals(SecurityPolicy.supportingTokens.getTokenName())) {
+            return new SupportingToken(Constants.SUPPORTING_TOKEN_SUPPORTING);
+        } else if (name.getLocalPart().equals(SecurityPolicy.endorsingSupportingTokens.getTokenName())) {
+            return new SupportingToken(Constants.SUPPORTING_TOKEN_ENDORSING);
+        } else if (name.getLocalPart().equals(SecurityPolicy.usernameToken.getTokenName())) {
+            return new UsernameToken();
+        } else if (name.getLocalPart().equals(SecurityPolicy.wss10.getTokenName())) {
+            return new Wss10();
+        } else if (name.getLocalPart().equals(SecurityPolicy.wss11.getTokenName())) {
+            return new Wss11();
+        } else if (name.getLocalPart().equals(SecurityPolicy.initiatorToken.getTokenName())) {
+            return new InitiatorToken();
+        } else if (name.getLocalPart().equals(SecurityPolicy.recipientToken.getTokenName())) {
+            return new RecipientToken();
+        } else {
+            log.error("Unsuppotred: " + name.getLocalPart());
+            throw new WSSPolicyException("Unsuppotred complex assertion :" + name.getLocalPart());
+        }
+    }
+}
diff --git a/src/org/apache/ws/security/policy/model/ProtectionToken.java b/src/org/apache/ws/security/policy/model/ProtectionToken.java
new file mode 100644
index 0000000..1493ade
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/ProtectionToken.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class ProtectionToken extends PolicyEngineData implements TokenWrapper {
+    
+    private Token protectionToken;
+
+    /**
+     * @return Returns the protectionToken.
+     */
+    public Token getProtectionToken() {
+        return protectionToken;
+    }
+
+    /**
+     * @param protectionToken The protectionToken to set.
+     */
+    public void setProtectionToken(Token protectionToken) {
+        this.protectionToken = protectionToken;
+    }
+
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.setProtectionToken(tok);
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/RecipientToken.java b/src/org/apache/ws/security/policy/model/RecipientToken.java
new file mode 100644
index 0000000..3295b00
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/RecipientToken.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class RecipientToken extends PolicyEngineData implements TokenWrapper {
+    
+    private Token recipientToken;
+
+    /**
+     * @return Returns the receipientToken.
+     */
+    public Token getRecipientToken() {
+        return recipientToken;
+    }
+
+    /**
+     * @param receipientToken The receipientToken to set.
+     */
+    public void setRecipientToken(Token receipientToken) {
+        this.recipientToken = receipientToken;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.policy.TokenWrapper#setToken(org.apache.ws.security.policy.Token)
+     */
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.setRecipientToken(tok);
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/RootPolicyEngineData.java b/src/org/apache/ws/security/policy/model/RootPolicyEngineData.java
new file mode 100644
index 0000000..1705895
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/RootPolicyEngineData.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import java.util.ArrayList;
+
+public class RootPolicyEngineData extends PolicyEngineData {
+
+    private ArrayList topLevelPEDs = new ArrayList();
+    
+    public void addTopLevelPED(PolicyEngineData ped) {
+        if(!topLevelPEDs.contains(ped)) {
+            this.topLevelPEDs.add(ped);
+        }
+    }
+    
+    public ArrayList getTopLevelPEDs() {
+        return this.topLevelPEDs;
+    }
+}
diff --git a/src/org/apache/ws/security/policy/model/SignatureToken.java b/src/org/apache/ws/security/policy/model/SignatureToken.java
new file mode 100644
index 0000000..beeabd2
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SignatureToken.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class SignatureToken extends PolicyEngineData implements TokenWrapper {
+
+    private Token signatureToken;
+
+    /**
+     * @return Returns the signatureToken.
+     */
+    public Token getSignatureToken() {
+        return signatureToken;
+    }
+
+    /**
+     * @param signatureToken The signatureToken to set.
+     */
+    public void setSignatureToken(Token signatureToken) {
+        this.signatureToken = signatureToken;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.policy.TokenWrapper#setToken(org.apache.ws.security.policy.Token)
+     */
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.setSignatureToken(tok);
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/SignedEncryptedElements.java b/src/org/apache/ws/security/policy/model/SignedEncryptedElements.java
new file mode 100644
index 0000000..62e21f3
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SignedEncryptedElements.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import java.util.ArrayList;
+
+public class SignedEncryptedElements extends PolicyEngineData {
+
+    private ArrayList xPathExpressions = new ArrayList();
+    private String xPathVersion;
+    
+    /**
+     * Just a flag to identify whether this holds 
+     * sign element info or encr elements info 
+     */
+    private boolean signedElements;
+    
+    public SignedEncryptedElements(boolean signedElements) {
+        this.signedElements = signedElements;
+    }
+    
+    /**
+     * @return Returns the xPathExpressions.
+     */
+    public ArrayList getXPathExpressions() {
+        return xPathExpressions;
+    }
+
+    public void addXPathExpression(String expr) {
+        this.xPathExpressions.add(expr);
+    }
+
+    /**
+     * @return Returns the xPathVersion.
+     */
+    public String getXPathVersion() {
+        return xPathVersion;
+    }
+
+    /**
+     * @param pathVersion The xPathVersion to set.
+     */
+    public void setXPathVersion(String pathVersion) {
+        xPathVersion = pathVersion;
+    }
+
+    /**
+     * @return Returns the signedElemets.
+     */
+    public boolean isSignedElements() {
+        return signedElements;
+    }
+    
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/SignedEncryptedParts.java b/src/org/apache/ws/security/policy/model/SignedEncryptedParts.java
new file mode 100644
index 0000000..9bb4c6d
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SignedEncryptedParts.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import java.util.ArrayList;
+
+public class SignedEncryptedParts extends PolicyEngineData {
+
+    private boolean body;
+    
+    private ArrayList headers = new ArrayList();
+    
+    private boolean signedParts;
+    
+    public SignedEncryptedParts(boolean signedParts) {
+        this.signedParts = signedParts;
+    }
+
+    /**
+     * @return Returns the body.
+     */
+    public boolean isBody() {
+        return body;
+    }
+
+    /**
+     * @param body The body to set.
+     */
+    public void setBody(boolean body) {
+        this.body = body;
+    }
+
+    /**
+     * @return Returns the headers.
+     */
+    public ArrayList getHeaders() {
+        return this.headers;
+    }
+
+    /**
+     * @param headers The headers to set.
+     */
+    public void addHeader(Header header) {
+        this.headers.add(header);
+    }
+
+    /**
+     * @return Returns the signedParts.
+     */
+    public boolean isSignedParts() {
+        return signedParts;
+    }
+    
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/SupportingToken.java b/src/org/apache/ws/security/policy/model/SupportingToken.java
new file mode 100644
index 0000000..6bbdbe3
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SupportingToken.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import java.util.ArrayList;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class SupportingToken extends PolicyEngineData implements AlgorithmWrapper, TokenWrapper {
+
+    /**
+     * Type of SupportingToken
+     * @see SupportingToken#SUPPORTING
+     * @see SupportingToken#ENDORSING
+     * @see SupportingToken#SIGNED
+     * @see SupportingToken#SIGNED_ENDORSING
+     */
+    private int type;
+    
+    private AlgorithmSuite algorithmSuite;
+    
+    private ArrayList tokens = new ArrayList();
+    
+    private SignedEncryptedElements signedElements;
+    
+    private SignedEncryptedElements encryptedElements;
+    
+    private SignedEncryptedParts signedParts;
+    
+    private SignedEncryptedParts encryptedParts;
+    
+    public SupportingToken(int type) {
+        this.type = type;
+    }
+
+    /**
+     * @return Returns the algorithmSuite.
+     */
+    public AlgorithmSuite getAlgorithmSuite() {
+        return algorithmSuite;
+    }
+
+    /**
+     * @param algorithmSuite The algorithmSuite to set.
+     */
+    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
+        this.algorithmSuite = algorithmSuite;
+    }
+
+    /**
+     * @return Returns the token.
+     */
+    public ArrayList getToken() {
+        return tokens;
+    }
+
+    /**
+     * @param token The token to set.
+     */
+    public void addToken(Token token) {
+        this.tokens.add(token);
+    }
+
+    /**
+     * @return Returns the type.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * @param type The type to set.
+     */
+    public void setType(int type) {
+        this.type = type;
+    }
+
+    /**
+     * @return Returns the encryptedElements.
+     */
+    public SignedEncryptedElements getEncryptedElements() {
+        return encryptedElements;
+    }
+
+    /**
+     * @param encryptedElements The encryptedElements to set.
+     */
+    public void setEncryptedElements(SignedEncryptedElements encryptedElements) {
+        this.encryptedElements = encryptedElements;
+    }
+
+    /**
+     * @return Returns the encryptedParts.
+     */
+    public SignedEncryptedParts getEncryptedParts() {
+        return encryptedParts;
+    }
+
+    /**
+     * @param encryptedParts The encryptedParts to set.
+     */
+    public void setEncryptedParts(SignedEncryptedParts encryptedParts) {
+        this.encryptedParts = encryptedParts;
+    }
+
+    /**
+     * @return Returns the signedElements.
+     */
+    public SignedEncryptedElements getSignedElements() {
+        return signedElements;
+    }
+
+    /**
+     * @param signedElements The signedElements to set.
+     */
+    public void setSignedElements(SignedEncryptedElements signedElements) {
+        this.signedElements = signedElements;
+    }
+
+    /**
+     * @return Returns the signedParts.
+     */
+    public SignedEncryptedParts getSignedParts() {
+        return signedParts;
+    }
+
+    /**
+     * @param signedParts The signedParts to set.
+     */
+    public void setSignedParts(SignedEncryptedParts signedParts) {
+        this.signedParts = signedParts;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ws.security.policy.TokenWrapper#setToken(org.apache.ws.security.policy.Token)
+     */
+    public void setToken(Token tok) throws WSSPolicyException {
+        this.addToken(tok);
+    }
+}
diff --git a/src/org/apache/ws/security/policy/model/SymmetricAsymmetricBindingBase.java b/src/org/apache/ws/security/policy/model/SymmetricAsymmetricBindingBase.java
new file mode 100644
index 0000000..f22afef
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SymmetricAsymmetricBindingBase.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class SymmetricAsymmetricBindingBase extends Binding {
+
+    private String protectionOrder = Constants.SIGN_BEFORE_ENCRYPTING;
+    
+    private boolean signatureProtection;
+    
+    private boolean tokenProtection;
+    
+    private boolean entireHeaderAndBodySignatures;
+
+    /**
+     * @return Returns the entireHeaderAndBodySignatures.
+     */
+    public boolean isEntireHeaderAndBodySignatures() {
+        return entireHeaderAndBodySignatures;
+    }
+
+    /**
+     * @param entireHeaderAndBodySignatures The entireHeaderAndBodySignatures to set.
+     */
+    public void setEntireHeaderAndBodySignatures(
+            boolean entireHeaderAndBodySignatures) {
+        this.entireHeaderAndBodySignatures = entireHeaderAndBodySignatures;
+    }
+
+    /**
+     * @return Returns the protectionOrder.
+     */
+    public String getProtectionOrder() {
+        return protectionOrder;
+    }
+
+    /**
+     * @param protectionOrder The protectionOrder to set.
+     */
+    public void setProtectionOrder(String protectionOrder)
+            throws WSSPolicyException {
+        if(Constants.ENCRYPT_BEFORE_SIGNING.equals(protectionOrder) ||
+           Constants.SIGN_BEFORE_ENCRYPTING.equals(protectionOrder)) {
+            this.protectionOrder = protectionOrder;
+        } else {
+            throw new WSSPolicyException("Incorrect protection order value : "
+                    + protectionOrder);
+        }
+    }
+
+    /**
+     * @return Returns the signatureProtection.
+     */
+    public boolean isSignatureProtection() {
+        return signatureProtection;
+    }
+
+    /**
+     * @param signatureProtection The signatureProtection to set.
+     */
+    public void setSignatureProtection(boolean signatureProtection) {
+        this.signatureProtection = signatureProtection;
+    }
+
+    /**
+     * @return Returns the tokenProtection.
+     */
+    public boolean isTokenProtection() {
+        return tokenProtection;
+    }
+
+    /**
+     * @param tokenProtection The tokenProtection to set.
+     */
+    public void setTokenProtection(boolean tokenProtection) {
+        this.tokenProtection = tokenProtection;
+    }
+    
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/SymmetricBinding.java b/src/org/apache/ws/security/policy/model/SymmetricBinding.java
new file mode 100644
index 0000000..20e41ca
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/SymmetricBinding.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class SymmetricBinding extends SymmetricAsymmetricBindingBase {
+
+    private EncryptionToken encryptionToken;
+    
+    private SignatureToken signatureToken;
+    
+    private ProtectionToken protectionToken;
+
+    /**
+     * @return Returns the encryptionToken.
+     */
+    public EncryptionToken getEncryptionToken() {
+        return encryptionToken;
+    }
+
+    /**
+     * @param encryptionToken The encryptionToken to set.
+     */
+    public void setEncryptionToken(EncryptionToken encryptionToken) throws WSSPolicyException {
+        if(this.protectionToken != null) {
+            throw new WSSPolicyException("Cannot use an EncryptionToken in a " +
+                    "SymmetricBinding when there is a ProtectionToken");
+        }
+        this.encryptionToken = encryptionToken;
+    }
+
+    /**
+     * @return Returns the protectionToken.
+     */
+    public ProtectionToken getProtectionToken() {
+        return protectionToken;
+    }
+
+    /**
+     * @param protectionToken The protectionToken to set.
+     */
+    public void setProtectionToken(ProtectionToken protectionToken) throws WSSPolicyException {
+        if(this.encryptionToken != null || this.signatureToken != null) {
+            throw new WSSPolicyException("Cannot use a ProtectionToken in a " +
+            "SymmetricBinding when there is a SignatureToken or an" +
+            "EncryptionToken");
+        }
+        this.protectionToken = protectionToken;
+    }
+
+    /**
+     * @return Returns the signatureToken.
+     */
+    public SignatureToken getSignatureToken() {
+        return signatureToken;
+    }
+
+    /**
+     * @param signatureToken The signatureToken to set.
+     */
+    public void setSignatureToken(SignatureToken signatureToken) throws WSSPolicyException {
+        if(this.protectionToken != null) {
+            throw new WSSPolicyException("Cannot use a SignatureToken in a " +
+                    "SymmetricBinding when there is a ProtectionToken");
+        }
+        this.signatureToken = signatureToken;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Token.java b/src/org/apache/ws/security/policy/model/Token.java
new file mode 100644
index 0000000..76c6089
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Token.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public class Token extends PolicyEngineData {
+
+    /**
+     * Inclusiong property of a TokenAssertion
+     */
+    private String inclusion = Constants.INCLUDE_ALWAYS;
+    
+    /**
+     * Whether to derive keys or not
+     */
+    private boolean derivedKeys;
+    
+    /**
+     * @return Returns the inclusion.
+     */
+    public String getInclusion() {
+        return inclusion;
+    }
+
+    /**
+     * @param inclusion The inclusion to set.
+     */
+    public void setInclusion(String inclusion) throws WSSPolicyException {
+        if(Constants.INCLUDE_ALWAYS.equals(inclusion) || 
+           Constants.INCLUDE_ALWAYS_TO_RECIPIENT.equals(inclusion) ||
+           Constants.INCLUDE_NEVER.equals(inclusion) ||
+           Constants.INCLUDE_ONCE.equals(inclusion)) {
+            this.inclusion = inclusion;
+        } else {
+            throw new WSSPolicyException("Incorrect inclusion value: " + inclusion);
+        }
+    }
+    
+    /**
+     * @return Returns the derivedKeys.
+     */
+    public boolean isDerivedKeys() {
+        return derivedKeys;
+    }
+
+    /**
+     * @param derivedKeys The derivedKeys to set.
+     */
+    public void setDerivedKeys(boolean derivedKeys) {
+        this.derivedKeys = derivedKeys;
+    }    
+    
+}
\ No newline at end of file
diff --git a/src/org/apache/ws/security/policy/model/TokenWrapper.java b/src/org/apache/ws/security/policy/model/TokenWrapper.java
new file mode 100644
index 0000000..cd37841
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/TokenWrapper.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+import org.apache.ws.security.policy.WSSPolicyException;
+
+public interface TokenWrapper {
+
+    public void setToken(Token tok) throws WSSPolicyException;
+}
diff --git a/src/org/apache/ws/security/policy/model/TransportBinding.java b/src/org/apache/ws/security/policy/model/TransportBinding.java
new file mode 100644
index 0000000..ece156b
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/TransportBinding.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class TransportBinding extends Binding {
+    
+    private Token transportToken;
+
+    /**
+     * @return Returns the transportToken.
+     */
+    public Token getTransportToken() {
+        return transportToken;
+    }
+
+    /**
+     * @param transportToken The transportToken to set.
+     */
+    public void setTransportToken(Token transportToken) {
+        this.transportToken = transportToken;
+    }
+
+}
diff --git a/src/org/apache/ws/security/policy/model/UsernameToken.java b/src/org/apache/ws/security/policy/model/UsernameToken.java
new file mode 100644
index 0000000..c26fb76
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/UsernameToken.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class UsernameToken extends Token {
+    
+    private boolean useUTProfile11;
+
+    /**
+     * @return Returns the useUTProfile11.
+     */
+    public boolean isUseUTProfile11() {
+        return useUTProfile11;
+    }
+
+    /**
+     * @param useUTProfile11 The useUTProfile11 to set.
+     */
+    public void setUseUTProfile11(boolean useUTProfile11) {
+        this.useUTProfile11 = useUTProfile11;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Wss10.java b/src/org/apache/ws/security/policy/model/Wss10.java
new file mode 100644
index 0000000..0b57541
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Wss10.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class Wss10 extends PolicyEngineData {
+    
+    private boolean mustSupportRefKeyIdentifier;
+    private boolean MustSupportRefIssuerSerial;
+    private boolean MustSupportRefExternalURI;
+    private boolean MustSupportRefEmbeddedToken;
+    
+    /**
+     * @return Returns the mustSupportRefEmbeddedToken.
+     */
+    public boolean isMustSupportRefEmbeddedToken() {
+        return MustSupportRefEmbeddedToken;
+    }
+    /**
+     * @param mustSupportRefEmbeddedToken The mustSupportRefEmbeddedToken to set.
+     */
+    public void setMustSupportRefEmbeddedToken(boolean mustSupportRefEmbeddedToken) {
+        MustSupportRefEmbeddedToken = mustSupportRefEmbeddedToken;
+    }
+    /**
+     * @return Returns the mustSupportRefExternalURI.
+     */
+    public boolean isMustSupportRefExternalURI() {
+        return MustSupportRefExternalURI;
+    }
+    /**
+     * @param mustSupportRefExternalURI The mustSupportRefExternalURI to set.
+     */
+    public void setMustSupportRefExternalURI(boolean mustSupportRefExternalURI) {
+        MustSupportRefExternalURI = mustSupportRefExternalURI;
+    }
+    /**
+     * @return Returns the mustSupportRefIssuerSerial.
+     */
+    public boolean isMustSupportRefIssuerSerial() {
+        return MustSupportRefIssuerSerial;
+    }
+    /**
+     * @param mustSupportRefIssuerSerial The mustSupportRefIssuerSerial to set.
+     */
+    public void setMustSupportRefIssuerSerial(boolean mustSupportRefIssuerSerial) {
+        MustSupportRefIssuerSerial = mustSupportRefIssuerSerial;
+    }
+    /**
+     * @return Returns the mustSupportRefKeyIdentifier.
+     */
+    public boolean isMustSupportRefKeyIdentifier() {
+        return mustSupportRefKeyIdentifier;
+    }
+    /**
+     * @param mustSupportRefKeyIdentifier The mustSupportRefKeyIdentifier to set.
+     */
+    public void setMustSupportRefKeyIdentifier(boolean mustSupportRefKeyIdentifier) {
+        this.mustSupportRefKeyIdentifier = mustSupportRefKeyIdentifier;
+    }
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/Wss11.java b/src/org/apache/ws/security/policy/model/Wss11.java
new file mode 100644
index 0000000..45a280b
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/Wss11.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class Wss11 extends Wss10 {
+    
+    private boolean MustSupportRefThumbprint;
+    private boolean MustSupportRefEncryptedKey;
+    private boolean RequireSignatureConfirmation;
+    
+    /**
+     * @return Returns the mustSupportRefEncryptedKey.
+     */
+    public boolean isMustSupportRefEncryptedKey() {
+        return MustSupportRefEncryptedKey;
+    }
+    /**
+     * @param mustSupportRefEncryptedKey The mustSupportRefEncryptedKey to set.
+     */
+    public void setMustSupportRefEncryptedKey(boolean mustSupportRefEncryptedKey) {
+        MustSupportRefEncryptedKey = mustSupportRefEncryptedKey;
+    }
+    /**
+     * @return Returns the mustSupportRefThumbprint.
+     */
+    public boolean isMustSupportRefThumbprint() {
+        return MustSupportRefThumbprint;
+    }
+    /**
+     * @param mustSupportRefThumbprint The mustSupportRefThumbprint to set.
+     */
+    public void setMustSupportRefThumbprint(boolean mustSupportRefThumbprint) {
+        MustSupportRefThumbprint = mustSupportRefThumbprint;
+    }
+    /**
+     * @return Returns the requireSignatureConfirmation.
+     */
+    public boolean isRequireSignatureConfirmation() {
+        return RequireSignatureConfirmation;
+    }
+    /**
+     * @param requireSignatureConfirmation The requireSignatureConfirmation to set.
+     */
+    public void setRequireSignatureConfirmation(boolean requireSignatureConfirmation) {
+        RequireSignatureConfirmation = requireSignatureConfirmation;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/model/X509Token.java b/src/org/apache/ws/security/policy/model/X509Token.java
new file mode 100644
index 0000000..02ea77b
--- /dev/null
+++ b/src/org/apache/ws/security/policy/model/X509Token.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.model;
+
+public class X509Token extends Token {
+
+    private boolean requireKeyIdentifierReference;
+    
+    private boolean requireIssuerSerialReference;
+    
+    private boolean requireEmbeddedTokenReference;
+    
+    private boolean requireThumbprintReference;
+    
+    private String tokenVersionAndType;
+
+    /**
+     * @return Returns the requireEmbeddedTokenReference.
+     */
+    public boolean isRequireEmbeddedTokenReference() {
+        return requireEmbeddedTokenReference;
+    }
+
+    /**
+     * @param requireEmbeddedTokenReference The requireEmbeddedTokenReference to set.
+     */
+    public void setRequireEmbeddedTokenReference(
+            boolean requireEmbeddedTokenReference) {
+        this.requireEmbeddedTokenReference = requireEmbeddedTokenReference;
+    }
+
+    /**
+     * @return Returns the requireIssuerSerialReference.
+     */
+    public boolean isRequireIssuerSerialReference() {
+        return requireIssuerSerialReference;
+    }
+
+    /**
+     * @param requireIssuerSerialReference The requireIssuerSerialReference to set.
+     */
+    public void setRequireIssuerSerialReference(boolean requireIssuerSerialReference) {
+        this.requireIssuerSerialReference = requireIssuerSerialReference;
+    }
+
+    /**
+     * @return Returns the requireKeyIdentifierReference.
+     */
+    public boolean isRequireKeyIdentifierReference() {
+        return requireKeyIdentifierReference;
+    }
+
+    /**
+     * @param requireKeyIdentifierReference The requireKeyIdentifierReference to set.
+     */
+    public void setRequireKeyIdentifierReference(
+            boolean requireKeyIdentifierReference) {
+        this.requireKeyIdentifierReference = requireKeyIdentifierReference;
+    }
+
+    /**
+     * @return Returns the requireThumbprintReference.
+     */
+    public boolean isRequireThumbprintReference() {
+        return requireThumbprintReference;
+    }
+
+    /**
+     * @param requireThumbprintReference The requireThumbprintReference to set.
+     */
+    public void setRequireThumbprintReference(boolean requireThumbprintReference) {
+        this.requireThumbprintReference = requireThumbprintReference;
+    }
+
+    /**
+     * @return Returns the tokenVersionAndType.
+     */
+    public String getTokenVersionAndType() {
+        return tokenVersionAndType;
+    }
+
+    /**
+     * @param tokenVersionAndType The tokenVersionAndType to set.
+     */
+    public void setTokenVersionAndType(String tokenVersionAndType) {
+        this.tokenVersionAndType = tokenVersionAndType;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/parser/SecurityPolicy.java b/src/org/apache/ws/security/policy/parser/SecurityPolicy.java
new file mode 100644
index 0000000..f5ed1be
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/SecurityPolicy.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.parser;
+
+public class SecurityPolicy {
+
+	public static final SecurityPolicyToken signedParts = new SecurityPolicyToken("SignedParts",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken header = new SecurityPolicyToken("Header",
+			SecurityPolicyToken.SIMPLE_TOKEN, new String[] { "Name",
+					"Namespace" });
+
+	public static final SecurityPolicyToken body = new SecurityPolicyToken("Body",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken signedElements = new SecurityPolicyToken(
+			"SignedElements", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "XPathVersion" });
+
+	public static final SecurityPolicyToken xPath = new SecurityPolicyToken(
+			"XPath",
+			SecurityPolicyToken.SIMPLE_TOKEN | SecurityPolicyToken.WITH_CONTENT,
+			null);
+
+	public static final SecurityPolicyToken encryptedParts = new SecurityPolicyToken(
+			"EncryptedParts", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken encryptedElements = new SecurityPolicyToken(
+			"EncryptedElements", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "XPathVersion" });
+
+	public static final SecurityPolicyToken requiredElements = new SecurityPolicyToken(
+			"RequiredElements", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "XPathVersion" });
+
+	public static final SecurityPolicyToken usernameToken = new SecurityPolicyToken(
+			"UsernameToken", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "IncludeToken" });
+
+	public static final SecurityPolicyToken wssUsernameToken10 = new SecurityPolicyToken(
+			"WssUsernameToken10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssUsernameToken11 = new SecurityPolicyToken(
+			"WssUsernameToken11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken issuedToken = new SecurityPolicyToken("IssuedToken",
+			SecurityPolicyToken.COMPLEX_TOKEN, new String[] { "IncludeToken" });
+
+	public static final SecurityPolicyToken issuer = new SecurityPolicyToken(
+			"Issuer",
+			SecurityPolicyToken.SIMPLE_TOKEN | SecurityPolicyToken.WITH_CONTENT,
+			null);
+
+	public static final SecurityPolicyToken requestSecurityTokenTemplate = new SecurityPolicyToken(
+			"RequestSecurityTokenTemplate", SecurityPolicyToken.COMPLEX_TOKEN
+					| SecurityPolicyToken.WITH_CONTENT,
+			new String[] { "TrustVersion" });
+
+	public static final SecurityPolicyToken requireDerivedKeys = new SecurityPolicyToken(
+			"RequireDerivedKeys", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken requireExternalReference = new SecurityPolicyToken(
+			"RequireExternalReference", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken requireInternalReference = new SecurityPolicyToken(
+			"RequireInternalReference", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken x509Token = new SecurityPolicyToken("X509Token",
+			SecurityPolicyToken.COMPLEX_TOKEN, new String[] { "IncludeToken" });
+
+	public static final SecurityPolicyToken requireKeyIdentifierReference = new SecurityPolicyToken(
+			"RequireKeyIdentifierReference", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken requireIssuerSerialReference = new SecurityPolicyToken(
+			"RequireIssuerSerialReference", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken requireEmbeddedTokenReference = new SecurityPolicyToken(
+			"RequireEmbeddedTokenReference", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken requireThumbprintReference = new SecurityPolicyToken(
+			"RequireThumbprintReference", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken wssX509V1Token10 = new SecurityPolicyToken(
+			"WssX509V1Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509V3Token10 = new SecurityPolicyToken(
+			"WssX509V3Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509Pkcs7Token10 = new SecurityPolicyToken(
+			"WssX509Pkcs7Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509PkiPathV1Token10 = new SecurityPolicyToken(
+			"WssX509PkiPathV1Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509V1Token11 = new SecurityPolicyToken(
+			"WssX509V1Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509V3Token11 = new SecurityPolicyToken(
+			"WssX509V3Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509Pkcs7Token11 = new SecurityPolicyToken(
+			"WssX509Pkcs7Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssX509PkiPathV1Token11 = new SecurityPolicyToken(
+			"WssX509PkiPathV1Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken kerberosToken = new SecurityPolicyToken(
+			"KerberosToken", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "IncludeToken" });
+
+	// requireDerivedKeys already defined for issuedToken
+	// requireKeyIdentifierReference already defined for x509Token
+	public static final SecurityPolicyToken wssKerberosV5ApReqToken11 = new SecurityPolicyToken(
+			"WssKerberosV5ApReqToken11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssGssKerberosV5ApReqToken11 = new SecurityPolicyToken(
+			"WssGssKerberosV5ApReqToken11", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken spnegoContextToken = new SecurityPolicyToken(
+			"SpnegoContextToken", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "IncludeToken" });
+
+	// issuer already defined for issuedToken
+	// requireDerivedKeys already defined for issuedToken
+
+	public static final SecurityPolicyToken securityContextToken = new SecurityPolicyToken(
+			"SecurityContextToken", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "IncludeToken" });
+
+	// requireDerivedKeys already defined for issuedToken
+	public static final SecurityPolicyToken requireExternalUriReference = new SecurityPolicyToken(
+			"RequireExternalUriReference", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken sc10SecurityContextToken = new SecurityPolicyToken(
+			"SC10SecurityContextToken", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken secureConversationToken = new SecurityPolicyToken(
+			"SecureConversationToken", SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "IncludeToken" });
+
+	// issuer already defined for issuedToken
+	// requireDerivedKeys already defined for issuedToken
+	// requireExternalUriReference is already defined for SecurityContextToken
+	// sc10SecurityContextToken is already defined for SecurityContextToken
+	public static final SecurityPolicyToken bootstrapPolicy = new SecurityPolicyToken(
+			"BootstrapPolicy", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken samlToken = new SecurityPolicyToken("SamlToken",
+			SecurityPolicyToken.COMPLEX_TOKEN, new String[] { "IncludeToken" });
+
+	// requireDerivedKeys already defined for issuedToken
+	// requireKeyIdentifierReference already defined for x509Token
+	public static final SecurityPolicyToken wssSamlV10Token10 = new SecurityPolicyToken(
+			"WssSamlV10Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssSamlV11Token10 = new SecurityPolicyToken(
+			"WssSamlV11Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssSamlV10Token11 = new SecurityPolicyToken(
+			"WssSamlV10Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssSamlV11Token11 = new SecurityPolicyToken(
+			"WssSamlV11Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssSamlV20Token11 = new SecurityPolicyToken(
+			"WssSamlV20Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken relToken = new SecurityPolicyToken("RelToken",
+			SecurityPolicyToken.COMPLEX_TOKEN, new String[] { "IncludeToken" });
+
+	// requireDerivedKeys already defined for issuedToken
+	// requireKeyIdentifierReference already defined for x509Token
+	public static final SecurityPolicyToken wssRelV10Token10 = new SecurityPolicyToken(
+			"WssRelV10Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssRelV20Token10 = new SecurityPolicyToken(
+			"WssRelV20Token10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssRelV10Token11 = new SecurityPolicyToken(
+			"WssRelV10Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken wssRelV20Token11 = new SecurityPolicyToken(
+			"WssRelV20Token11", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken httpsToken = new SecurityPolicyToken("HttpsToken",
+			SecurityPolicyToken.COMPLEX_TOKEN,
+			new String[] { "RequireClientCertificate" });
+
+	public static final SecurityPolicyToken algorithmSuite = new SecurityPolicyToken("AlgorithmSuite",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken basic256 = new SecurityPolicyToken("Basic256",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic192 = new SecurityPolicyToken("Basic192",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic128 = new SecurityPolicyToken("Basic128",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken tripleDes = new SecurityPolicyToken("TripleDes",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic256Rsa15 = new SecurityPolicyToken(
+			"Basic256Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic192Rsa15 = new SecurityPolicyToken(
+			"Basic192Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic128Rsa15 = new SecurityPolicyToken(
+			"Basic128Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken tripleDesRsa15 = new SecurityPolicyToken(
+			"TripleDesRsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic256Sha256 = new SecurityPolicyToken(
+			"Basic256Sha256", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic192Sha256 = new SecurityPolicyToken(
+			"Basic192Sha256", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic128Sha256 = new SecurityPolicyToken(
+			"Basic128Sha256", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken tripleDesSha256 = new SecurityPolicyToken(
+			"TripleDesSha256", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic256Sha256Rsa15 = new SecurityPolicyToken(
+			"Basic256Sha256Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic192Sha256Rsa15 = new SecurityPolicyToken(
+			"Basic192Sha256Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken basic128Sha256Rsa15 = new SecurityPolicyToken(
+			"Basic128Sha256Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken tripleDesSha256Rsa15 = new SecurityPolicyToken(
+			"TripleDesSha256Rsa15", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken inclusiveC14N = new SecurityPolicyToken(
+			"InclusiveC14N", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken soapNormalization10 = new SecurityPolicyToken(
+			"SoapNormalization10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken strTransform10 = new SecurityPolicyToken(
+			"StrTransform10", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken xPath10 = new SecurityPolicyToken("XPath10",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken xPathFilter20 = new SecurityPolicyToken(
+			"XPathFilter20", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken layout = new SecurityPolicyToken("Layout",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken strict = new SecurityPolicyToken("Strict",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken lax = new SecurityPolicyToken("Lax",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken laxTsFirst = new SecurityPolicyToken("LaxTsFirst",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken laxTsLast = new SecurityPolicyToken("LaxTsLast",
+			SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken transportBinding = new SecurityPolicyToken(
+			"TransportBinding", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken transportToken = new SecurityPolicyToken(
+			"TransportToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	// algorithmSuite and layout see above
+	public static final SecurityPolicyToken includeTimestamp = new SecurityPolicyToken(
+			"IncludeTimestamp", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken symmetricBinding = new SecurityPolicyToken(
+			"SymmetricBinding", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken encryptionToken = new SecurityPolicyToken(
+			"EncryptionToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken signatureToken = new SecurityPolicyToken(
+			"SignatureToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken protectionToken = new SecurityPolicyToken(
+			"ProtectionToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	// algorithmSuite and layout see above
+	// includeTimestamp already defined for transport binding
+	public static final SecurityPolicyToken encryptBeforeSigning = new SecurityPolicyToken(
+			"EncryptBeforeSigning", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+    public static final SecurityPolicyToken signBeforeEncrypting = new SecurityPolicyToken(
+            "SignBeforeEncrypting", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+    public static final SecurityPolicyToken encryptSignature = new SecurityPolicyToken(
+			"EncryptSignature", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken protectTokens = new SecurityPolicyToken(
+			"ProtectTokens", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken onlySignEntireHeadersAndBody = new SecurityPolicyToken(
+			"OnlySignEntireHeadersAndBody", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken asymmetricBinding = new SecurityPolicyToken(
+			"AsymmetricBinding", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken initiatorToken = new SecurityPolicyToken(
+			"InitiatorToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken recipientToken = new SecurityPolicyToken(
+			"RecipientToken", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	// all other tokens for asymmetric already defined above
+
+	public static final SecurityPolicyToken supportingTokens = new SecurityPolicyToken(
+			"SupportingTokens", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken signedSupportingTokens = new SecurityPolicyToken(
+			"SignedSupportingTokens", SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken endorsingSupportingTokens = new SecurityPolicyToken(
+			"EndorsingSupportingTokens", SecurityPolicyToken.COMPLEX_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken signedEndorsingSupportingTokens = new SecurityPolicyToken(
+			"SignedEndorsingSupportingTokens",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken wss10 = new SecurityPolicyToken("Wss10",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken mustSupportRefKeyIdentifier = new SecurityPolicyToken(
+			"MustSupportRefKeyIdentifier", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken mustSupportRefIssuerSerial = new SecurityPolicyToken(
+			"MustSupportRefIssuerSerial", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken mustSupportRefExternalUri = new SecurityPolicyToken(
+			"MustSupportRefExternalURI", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken mustSupportRefEmbeddedToken = new SecurityPolicyToken(
+			"MustSupportRefEmbeddedToken", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken wss11 = new SecurityPolicyToken("Wss11",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	// all from wss10
+	public static final SecurityPolicyToken mustSupportRefThumbprint = new SecurityPolicyToken(
+			"MustSupportRefThumbprint", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken mustSupportRefEncryptedKey = new SecurityPolicyToken(
+			"MustSupportRefEncryptedKey", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken requireSignatureConfirmation = new SecurityPolicyToken(
+			"RequireSignatureConfirmation", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken trust10 = new SecurityPolicyToken("Trust10",
+			SecurityPolicyToken.COMPLEX_TOKEN, null);
+
+	public static final SecurityPolicyToken mustSupportClientChallenge = new SecurityPolicyToken(
+			"MustSupportClientChallenge", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken mustSupportServerChallenge = new SecurityPolicyToken(
+			"MustSupportServerChallenge", SecurityPolicyToken.SIMPLE_TOKEN,
+			null);
+
+	public static final SecurityPolicyToken requireClientEntropy = new SecurityPolicyToken(
+			"RequireClientEntropy", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken requireServerEntropy = new SecurityPolicyToken(
+			"RequireServerEntropy", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final SecurityPolicyToken mustSupportIssuedTokens = new SecurityPolicyToken(
+			"MustSupportIssuedTokens", SecurityPolicyToken.SIMPLE_TOKEN, null);
+
+	public static final String includeNever = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never";
+
+	public static final String includeOnce = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once";
+
+	public static final String includeAlways = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always";
+
+}
diff --git a/src/org/apache/ws/security/policy/parser/SecurityPolicyToken.java b/src/org/apache/ws/security/policy/parser/SecurityPolicyToken.java
new file mode 100644
index 0000000..5fbb18c
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/SecurityPolicyToken.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.parser;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class SecurityPolicyToken {
+
+	/**
+	 * The following values describe the type of the security token. A complex
+	 * token starts a transaction because it contains nested tokens. A simple
+	 * token does not contain nested tokens but stands allone an defines a
+	 * simple assertion or property.
+	 * 
+	 * If Content is set then this token contains additional text content, e.g.
+	 * XPath expressions.
+	 */
+	public static final int COMPLEX_TOKEN = 1;
+
+	public static final int SIMPLE_TOKEN = 2;
+
+	public static final int WITH_CONTENT = 100;
+
+	private String tokenName;
+
+	private int tokenType = 0;
+
+	// private boolean supported = false;
+
+	private String[] attributes = null;
+
+	private Object handler = null;
+
+	private Method processTokenMethod = null;
+
+	private ArrayList childTokens = null;
+
+	/**
+	 * Create a SecurityPolicyToken data structure.
+	 * 
+	 * @param token
+	 *            The name of the token, equals to to local name of the XML
+	 *            element
+	 * @param type
+	 *            Type of the token. Either complex or simple. Can have a flag
+	 *            if the token containes some data.
+	 * @param attribs
+	 *            The names of allowed attributes on this token
+	 * @param h
+	 *            The handler object that implements the processing method. The
+	 *            name of a processing method is constructed by prepending a
+	 *            "do" to the token name
+	 * @throws SecurityException
+	 * @throws NoSuchMethodException
+	 */
+	public SecurityPolicyToken(String token, int type, String[] attribs,
+			Object h) throws SecurityException, NoSuchMethodException {
+		this(token, type, attribs);
+
+		setProcessTokenMethod(h);
+	}
+
+	/**
+	 * Create a SecurityPolicyToken data structure.
+	 * 
+	 * @param token
+	 *            The name of the token, equals to to local name of the XML
+	 *            element
+	 * @param type
+	 *            Type of the token. Either complex or simple. Can have a flag
+	 *            if the token containes some data.
+	 * @param attribs
+	 *            The names of allowed attributes on this token processing
+	 *            method is constructed by prepending a "do" to the token name
+	 */
+	public SecurityPolicyToken(String token, int type, String[] attribs) {
+		tokenName = token;
+		tokenType = type;
+		attributes = attribs;
+
+		if (tokenType == COMPLEX_TOKEN) {
+			childTokens = new ArrayList();
+		}
+	}
+
+	/**
+	 * @return Returns the attributes.
+	 */
+	public String[] getAttributes() {
+		return attributes;
+	}
+
+	/**
+	 * Set the method which processes this security token.
+	 * 
+	 * @param h
+	 *            The handler object that implements the processing method. The
+	 *            name of a processing method is constructed by prepending a
+	 *            "do" to the token name.
+	 * 
+	 * @throws NoSuchMethodException
+	 */
+	public void setProcessTokenMethod(Object h) throws NoSuchMethodException {
+
+		if (h == null) {
+			return;
+		}
+		handler = h;
+		Class handlerCls = h.getClass();
+		Class[] parameters = new Class[] { SecurityProcessorContext.class };
+
+		processTokenMethod = handlerCls.getDeclaredMethod("do" + tokenName,
+				parameters);
+	}
+
+	/**
+	 * Invoke the processing method for this token.
+	 * 
+	 * @param spc
+	 *            The SecurityProcessContext handed over to the processing
+	 *            method
+	 * @return True if the token is processed successfully
+	 * @throws IllegalArgumentException
+	 * @throws IllegalAccessException
+	 * @throws InvocationTargetException
+	 */
+	public boolean invokeProcessTokenMethod(SecurityProcessorContext spc)
+			throws IllegalArgumentException, IllegalAccessException,
+			InvocationTargetException {
+
+		if (processTokenMethod == null) {
+			return false;
+		}
+		Object[] parameter = new Object[] { spc };
+		Object ret = processTokenMethod.invoke(handler, parameter);
+		Boolean bool;
+		if (ret instanceof Boolean) {
+			bool = (Boolean) ret;
+			return bool.booleanValue();
+		}
+		return false;
+	}
+
+	/**
+	 * @return Returns the tokenName.
+	 */
+	public String getTokenName() {
+		return tokenName;
+	}
+
+	/**
+	 * Add a Child token to this complex token.
+	 * 
+	 * @param spt
+	 *            The child token to add to this Complex token
+	 */
+	public void setChildToken(SecurityPolicyToken spt) {
+		childTokens.add(spt);
+	}
+
+	/**
+	 * Gets a named child token,
+	 * 
+	 * @param sptName
+	 *            The token name to check for
+	 * @return the SecurityPolicyToken if this token contains the named token as
+	 *         child token, null otherwise.
+	 */
+	public SecurityPolicyToken getChildToken(String sptName) {
+		Iterator it = childTokens.iterator();
+		while (it.hasNext()) {
+			SecurityPolicyToken tmpSpt = (SecurityPolicyToken) it.next();
+			if (sptName.equals(tmpSpt.getTokenName())) {
+				return tmpSpt;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Remove a named child token,
+	 * 
+	 * @param sptName
+	 *            The token name to remove
+	 */
+	public void removeChildToken(String sptName) {
+		Iterator it = childTokens.iterator();
+		while (it.hasNext()) {
+			SecurityPolicyToken tmpSpt = (SecurityPolicyToken) it.next();
+			if (sptName.equals(tmpSpt.getTokenName())) {
+				childTokens.remove(tmpSpt);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Copy this SecurityPolicyToken and return the copy.
+	 * 
+	 * Produce a copy of this SPT. The imutable fields (token name, token type,
+	 * and attributes) are copied by reference. The child tokens are copied by
+	 * value thus they can be modified. The handler object and the associated
+	 * processing method are not copied and must be intialized.
+	 * 
+	 * @return A new SecurityPolicyToken
+	 */
+	public SecurityPolicyToken copy() {
+		SecurityPolicyToken spt = new SecurityPolicyToken(tokenName, tokenType,
+				attributes);
+		if (childTokens != null) {
+			Iterator it = childTokens.iterator();
+			while (it.hasNext()) {
+				SecurityPolicyToken tmpSpt = (SecurityPolicyToken) it.next();
+				spt.setChildToken(tmpSpt);
+			}
+		}
+		return spt;
+	}
+    
+    public int getTokenType() {
+        return this.tokenType;
+    }
+}
diff --git a/src/org/apache/ws/security/policy/parser/SecurityProcessorContext.java b/src/org/apache/ws/security/policy/parser/SecurityProcessorContext.java
new file mode 100644
index 0000000..a46f86b
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/SecurityProcessorContext.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.policy.parser;
+
+import java.util.ArrayList;
+
+import org.apache.ws.policy.PrimitiveAssertion;
+import org.apache.ws.security.policy.model.PolicyEngineData;
+import org.apache.ws.security.policy.model.RootPolicyEngineData;
+
+public class SecurityProcessorContext {
+	
+	public static final int NONE = 0;
+	public static final int START = 1;
+	public static final int COMMIT = 2;
+	public static final int ABORT = 3;
+
+	public static final String[] ACTION_NAMES = new String[]{"NONE", "START", "COMMIT", "ABORT"};
+	
+	private ArrayList tokenStack = new ArrayList();
+
+	private int tokenStackPointer = 0;
+	
+	private PrimitiveAssertion assertion = null;
+    
+    private ArrayList pedStack = new ArrayList();
+
+    private int pedStackPointer = 0;
+	private int action = NONE;
+    
+	public SecurityProcessorContext() {
+	}
+
+	/**
+	 * Gets the action to perform in the processing method.
+	 * 
+	 * @return The action
+	 */
+	public int getAction() {
+		return action;
+	}
+
+	/**
+	 * Sets to action to perform in the processing method.
+	 * 
+	 * @param act The actio to set. Either NONE, START, COMMIT, or ABORT
+	 */
+	public void setAction(int act) {
+		this.action = act;
+	}
+	/**
+	 * Get the current assertion that is being processed.
+	 * 
+	 * This is always a PrimitiveAssertion.
+	 * 
+	 * @return The current assertion.
+	 */
+	public PrimitiveAssertion getAssertion() {
+		return assertion;
+	}
+
+	/**
+	 * Set the current assertion that is being processed.
+	 * 
+	 * This is always a primitive assertion.
+	 * 
+	 * @param asrt The assertion to set
+	 */
+	public void setAssertion(PrimitiveAssertion asrt) {
+		this.assertion = asrt;
+	}
+
+	/**
+	 * Push a SecurityPolicyToken onto the token stack.
+	 * 
+	 * The pushed token becomes the current token. The current token is the
+	 * starting point for further parsing.
+	 * 
+	 * @param spt
+	 *            The SecurityPolicyToken to push on the stack
+	 */
+	public void pushSecurityToken(SecurityPolicyToken spt) {
+		tokenStack.add(tokenStackPointer, spt);
+		tokenStackPointer++;
+	}
+
+	/**
+	 * Pop a SecurityPolicyToken from the token stack.
+	 * 
+	 * If the stack contains at least one token the method pops the topmost
+	 * token from the stack and returns it. If the stack is empty the method
+	 * returns a <code>null</code>.
+	 * 
+	 * @return The topmost SecurityPolicyToken or null if the stack is empty.
+	 */
+	public SecurityPolicyToken popSecurityToken() {
+		if (tokenStackPointer > 0) {
+			tokenStackPointer--;
+			return (SecurityPolicyToken) tokenStack.get(tokenStackPointer);
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * Reads and returns the current SecurityPolicyToken.
+	 * 
+	 * If the stack contains at least one token the method reads the topmost
+	 * token from the stack and returns it. If the stack is empty the method
+	 * returns a <code>null</code>. The method does not remove the token from
+	 * the stack.
+	 * 
+	 * @return The topmost SecurityPolicyToken or null if the stack is empty.
+	 */
+	public SecurityPolicyToken readCurrentSecurityToken() {
+		if (tokenStackPointer > 0) {
+			return (SecurityPolicyToken) tokenStack.get(tokenStackPointer - 1);
+		} else {
+			return null;
+		}
+	}
+    
+    /**
+     * Push a PolicyEngineData onto the PED stack.
+     * 
+     * The pushed PED becomes the current PED. The current PED is the
+     * starting point for further processing.
+     * 
+     * @param ped
+     *            The PolicyEngineData to push on the stack
+     */
+    public void pushPolicyEngineData(PolicyEngineData ped) {
+        pedStack.add(pedStackPointer, ped);
+        pedStackPointer++;
+    }
+
+    /**
+     * Pop a PolicyEngineData from the PED stack.
+     * 
+     * If the stack contains at least one PolicyEngineData the method pops the topmost
+     * PolicyEngineData from the stack and returns it. If the stack is empty the method
+     * returns a <code>null</code>.
+     * 
+     * @return The topmost PolicyEngineData or null if the stack is empty.
+     */
+    public PolicyEngineData popPolicyEngineData() {
+        if (pedStackPointer > 0) {
+            pedStackPointer--;
+            return (PolicyEngineData) pedStack.get(pedStackPointer);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Reads and returns the current PolicyEngineData.
+     * 
+     * If the stack contains at least one PolicyEngineData the method reads the topmost
+     * PolicyEngineData from the stack and returns it. If the stack is empty the method
+     * returns a <code>null</code>. The method does not remove the PolicyEngineData from
+     * the stack.
+     * 
+     * @return The topmost PolicyEngineData or null if the stack is empty.
+     */
+    public PolicyEngineData readCurrentPolicyEngineData() {
+        if (pedStackPointer > 0) {
+            return (PolicyEngineData) pedStack.get(pedStackPointer - 1);
+        } else {
+            return null;
+        }
+    }
+
+    public PolicyEngineData readPreviousPolicyEngineData() {
+        if (pedStackPointer > 1) {
+            return (PolicyEngineData) pedStack.get(pedStackPointer - 2);
+        } else {
+            return null;
+        }
+    }
+    
+
+    public PolicyEngineData commitPolicyEngineData() {
+        if (pedStackPointer > 2) {
+            pedStackPointer--;
+            PolicyEngineData ped = (PolicyEngineData) pedStack.get(pedStackPointer);
+            return ped;
+        } else if(pedStackPointer == 2) {
+            RootPolicyEngineData rootData = (RootPolicyEngineData)this.pedStack.get(0);
+            rootData.addTopLevelPED(readCurrentPolicyEngineData());
+            pedStackPointer--;
+            return (PolicyEngineData) pedStack.get(pedStackPointer);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return Returns the pedStack.
+     */
+    public ArrayList getPedStack() {
+        return pedStack;
+    }
+    
+    
+}
diff --git a/src/org/apache/ws/security/policy/parser/WSSPolicyProcessor.java b/src/org/apache/ws/security/policy/parser/WSSPolicyProcessor.java
new file mode 100644
index 0000000..751649c
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/WSSPolicyProcessor.java
@@ -0,0 +1,398 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser;

+

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.lang.reflect.InvocationTargetException;

+import java.util.Iterator;

+import java.util.List;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.AndCompositeAssertion;

+import org.apache.ws.policy.Assertion;

+import org.apache.ws.policy.Policy;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.policy.XorCompositeAssertion;

+import org.apache.ws.policy.util.PolicyFactory;

+import org.apache.ws.policy.util.PolicyReader;

+import org.apache.ws.security.policy.Constants;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.PolicyEngineData;

+import org.apache.ws.security.policy.model.RootPolicyEngineData;

+import org.apache.ws.security.policy.parser.processors.AsymmetricBindingProcessor;

+import org.apache.ws.security.policy.parser.processors.EncryptedPartsElementsProcessor;

+import org.apache.ws.security.policy.parser.processors.EndorsingSupportingTokensProcessor;

+import org.apache.ws.security.policy.parser.processors.SignedEndorsingSupportingTokensProcessor;

+import org.apache.ws.security.policy.parser.processors.SignedPartsElementsProcessor;

+import org.apache.ws.security.policy.parser.processors.SignedSupportingTokensProcessor;

+import org.apache.ws.security.policy.parser.processors.SupportingTokensProcessor;

+import org.apache.ws.security.policy.parser.processors.SymmetricBindingProcessor;

+import org.apache.ws.security.policy.parser.processors.Wss10Processor;

+import org.apache.ws.security.policy.parser.processors.Wss11Processor;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ */

+

+public class WSSPolicyProcessor {

+    

+    private static Log log = LogFactory.getLog(WSSPolicyProcessor.class);

+

+    FileInputStream fis = null;

+

+    PolicyReader prdr = null;

+

+    Policy merged = null;

+

+    SecurityPolicyToken topLevel = new SecurityPolicyToken("_TopLevel_",

+            SecurityPolicyToken.COMPLEX_TOKEN, null);

+

+    public SecurityProcessorContext secProcessorContext = null;

+

+    public boolean setup() throws NoSuchMethodException {

+        prdr = PolicyFactory.getPolicyReader(PolicyFactory.DOM_POLICY_READER);

+

+        /*

+         * Initialize the top level security policy token.

+         */

+        SecurityPolicyToken spt = null;

+

+        SignedPartsElementsProcessor spep = new SignedPartsElementsProcessor();

+        spt = SecurityPolicy.signedParts.copy();

+        spt.setProcessTokenMethod(spep);

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.signedElements.copy();

+        spt.setProcessTokenMethod(spep);

+        topLevel.setChildToken(spt);

+

+        EncryptedPartsElementsProcessor epep = new EncryptedPartsElementsProcessor();

+        spt = SecurityPolicy.encryptedParts.copy();

+        spt.setProcessTokenMethod(epep);

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.encryptedElements.copy();

+        spt.setProcessTokenMethod(epep);

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.asymmetricBinding.copy();

+        spt.setProcessTokenMethod(new AsymmetricBindingProcessor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.symmetricBinding.copy();

+        spt.setProcessTokenMethod(new SymmetricBindingProcessor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.wss10.copy();

+        spt.setProcessTokenMethod(new Wss10Processor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.wss11.copy();

+        spt.setProcessTokenMethod(new Wss11Processor());

+        topLevel.setChildToken(spt);

+        

+        spt = SecurityPolicy.supportingTokens.copy();

+        spt.setProcessTokenMethod(new SupportingTokensProcessor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.signedSupportingTokens.copy();

+        spt.setProcessTokenMethod(new SignedSupportingTokensProcessor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.endorsingSupportingTokens.copy();

+        spt.setProcessTokenMethod(new EndorsingSupportingTokensProcessor());

+        topLevel.setChildToken(spt);

+

+        spt = SecurityPolicy.signedEndorsingSupportingTokens.copy();

+        spt.setProcessTokenMethod(new SignedEndorsingSupportingTokensProcessor());

+        topLevel.setChildToken(spt);

+

+        

+        /*

+         * Now get the initial PolicyEngineData, initialize it and put it onto

+         * the PED stack.

+         */

+        PolicyEngineData ped = new RootPolicyEngineData();

+        ped.initializeWithDefaults();

+        

+        /*

+         * Now get a context and push the top level token onto the token stack.

+         * The top level token is a special token that acts as anchor to start

+         * parsing.

+         */

+        secProcessorContext = new SecurityProcessorContext();

+        secProcessorContext.pushSecurityToken(topLevel);

+        secProcessorContext.pushPolicyEngineData(ped);

+

+        return true;

+    }

+

+    public boolean go(String[] args) {

+

+        merged = null;

+        for (int i = 0; i < args.length; i++) {

+            try {

+                fis = new FileInputStream(args[i]);

+            } catch (FileNotFoundException e) {

+                // TODO Auto-generated catch block

+                e.printStackTrace();

+            }

+

+            Policy newPolicy = prdr.readPolicy(fis);

+            newPolicy = (Policy) newPolicy.normalize();

+

+            if (merged == null) {

+                merged = newPolicy;

+            } else {

+                merged = (Policy) merged.merge(newPolicy);

+            }

+            try {

+                fis.close();

+            } catch (IOException e) {

+                // TODO Auto-generated catch block

+                e.printStackTrace();

+            }

+        }

+        if (processPolicy(merged)) {

+            log.debug("Security Policy sucessfully parsed");

+            return true;

+        } else {

+            log.debug("Security Policy not sucessfully parsed");

+            return false;

+        }

+    }

+

+    /**

+     * This method takes a normalized policy object, processes it and returns

+     * true if all assertion can be fulfilled.

+     * 

+     * Each policy must be nromalized accordig to the WS Policy framework

+     * specification. Therefore a policy has one child (wsp:ExactlyOne) that is

+     * a XorCompositeAssertion. This child may contain one or more other terms

+     * (alternatives). To match the policy one of these terms (alternatives)

+     * must match. If none of the contained terms match this policy cannot be

+     * enforced.

+     * 

+     * @param policy

+     *            The policy to process

+     * @return True if this policy can be enforced by the policy enforcement

+     *         implmentation

+     */

+    public boolean processPolicy(Policy policy) {

+

+        if (!policy.isNormalized()) {

+            throw new RuntimeException("Policy is not in normalized format");

+        }

+

+        XorCompositeAssertion xor = (XorCompositeAssertion) policy.getTerms()

+                .get(0);

+        List listOfPolicyAlternatives = xor.getTerms();

+

+        boolean success = false;

+        int numberOfAlternatives = listOfPolicyAlternatives.size();

+

+        for (int i = 0; !success && i < numberOfAlternatives; i++) {

+            AndCompositeAssertion aPolicyAlternative = (AndCompositeAssertion) listOfPolicyAlternatives

+                    .get(i);

+

+            List listOfAssertions = aPolicyAlternative.getTerms();

+

+            Iterator iterator = listOfAssertions.iterator();

+            /*

+             * Loop over all assertions in this alternative. If all assertions

+             * can be fulfilled then we choose this alternative and signal a

+             * success.

+             */

+            boolean all = true;

+            while (all && iterator.hasNext()) {

+                Assertion assertion = (Assertion) iterator.next();

+

+                /*

+                 * At this point we expect PrimitiveAssertions only.

+                 */

+                if (!(assertion instanceof PrimitiveAssertion)) {

+                    log.debug("Got a unexpected assertion type: "

+                            + assertion.getClass().getName());

+                    continue;

+                }

+                /*

+                 * We need to pick only the primitive assertions which contain a

+                 * WSSecurityPolicy policy assertion. For that we'll check the

+                 * namespace of the primitive assertion

+                 */

+                PrimitiveAssertion pa = (PrimitiveAssertion) assertion;

+                if (!(pa.getName().getNamespaceURI()

+                        .equals(Constants.SP_NS))) {

+                    log.debug("Got a unexpected assertion: "

+                            + pa.getName().getLocalPart());

+                    continue;

+                }

+                all = processPrimitiveAssertion((PrimitiveAssertion) assertion);

+            }

+            /*

+             * copy the status of assertion processing. If all is true then this

+             * alternative is "success"ful

+             */

+            success = all;

+        }

+        return success;

+    }

+

+    boolean processPrimitiveAssertion(PrimitiveAssertion pa) {

+        boolean commit = true;

+

+        commit = startPolicyTransaction(pa);

+

+        List terms = pa.getTerms();

+        if (commit && terms.size() > 0) {

+            for (int i = 0; commit && i < terms.size(); i++) {

+                Assertion assertion = (Assertion) pa.getTerms().get(i);

+                if (assertion instanceof Policy) {

+                    commit = processPolicy((Policy) assertion);

+                } else if (assertion instanceof PrimitiveAssertion) {

+                    commit = processPrimitiveAssertion((PrimitiveAssertion) assertion);

+                }

+            }

+        }

+        if (commit) {

+            commitPolicyTransaction(pa);

+        } else {

+            abortPolicyTransaction(pa);

+        }

+        return commit;

+    }

+

+    public boolean startPolicyTransaction(PrimitiveAssertion pa) {

+

+        String tokenName = pa.getName().getLocalPart();

+

+        SecurityPolicyToken spt = null;

+

+        /*

+         * Get the current security token from the context and check if the

+         * current token supports/contains this assertion as token. If yes set

+         * this token as current token (push onto stack), set the assertion into

+         * context and call the processing method for this token.

+         */

+        SecurityPolicyToken currentToken = secProcessorContext

+                .readCurrentSecurityToken();

+        if (currentToken == null) {

+            log.error("Internal error on token stack - No current token");

+            System.exit(1);

+        }

+        spt = currentToken.getChildToken(tokenName);

+        secProcessorContext.pushSecurityToken(spt);

+        secProcessorContext.setAssertion(pa);

+        secProcessorContext.setAction(SecurityProcessorContext.START);

+

+        boolean ret = false;

+        

+        try {

+

+            if (spt == null) {

+                log.error("Security token: '" + tokenName

+                                + "' unknown in context of '"

+                                + currentToken.getTokenName());

+                return false;

+            }

+            if(spt.getTokenType() == SecurityPolicyToken.COMPLEX_TOKEN && secProcessorContext.getAction() == SecurityProcessorContext.START) {

+                secProcessorContext.pushPolicyEngineData(PolicyEngineData.copy(pa.getName()));

+            }

+            ret = spt.invokeProcessTokenMethod(secProcessorContext);

+            

+        } catch (IllegalArgumentException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (IllegalAccessException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (InvocationTargetException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (WSSPolicyException e) {

+            e.printStackTrace();

+        } finally {

+            secProcessorContext.setAction(SecurityProcessorContext.NONE);

+        }

+        return ret;

+    }

+

+    public void abortPolicyTransaction(PrimitiveAssertion pa) {

+        SecurityPolicyToken currentToken = secProcessorContext

+                .readCurrentSecurityToken();

+        if (currentToken == null) {

+            secProcessorContext.popSecurityToken();

+            log.error("Abort transaction because of unknown token: '"

+                    + pa.getName().getLocalPart() + "'");

+            return;

+        }

+        secProcessorContext.setAssertion(pa);

+        secProcessorContext.setAction(SecurityProcessorContext.ABORT);

+        try {

+            currentToken.invokeProcessTokenMethod(secProcessorContext);

+        } catch (IllegalArgumentException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (IllegalAccessException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (InvocationTargetException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } finally {

+            secProcessorContext.setAction(SecurityProcessorContext.NONE);

+            secProcessorContext.popSecurityToken();

+            if(currentToken.getTokenType() == SecurityPolicyToken.COMPLEX_TOKEN) {

+            	secProcessorContext.popPolicyEngineData();

+            }

+        }

+    }

+

+    public void commitPolicyTransaction(PrimitiveAssertion pa) {

+        SecurityPolicyToken currentToken = secProcessorContext

+                .readCurrentSecurityToken();

+        if (currentToken == null) {

+            log.error("Internal error on token stack - Commiting an unknown token: "

+                            + pa.getName().getLocalPart() + "'");

+            System.exit(1);

+        }

+        secProcessorContext.setAssertion(pa);

+        secProcessorContext.setAction(SecurityProcessorContext.COMMIT);

+        try {

+            currentToken.invokeProcessTokenMethod(secProcessorContext);

+        } catch (IllegalArgumentException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (IllegalAccessException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } catch (InvocationTargetException e) {

+            // TODO Auto-generated catch block

+            e.printStackTrace();

+        } finally {

+            secProcessorContext.setAction(SecurityProcessorContext.NONE);

+            secProcessorContext.popSecurityToken();

+            if(currentToken.getTokenType() == SecurityPolicyToken.COMPLEX_TOKEN) {

+                secProcessorContext.commitPolicyEngineData();

+            }

+        }

+    }

+}

diff --git a/src/org/apache/ws/security/policy/parser/package.html b/src/org/apache/ws/security/policy/parser/package.html
new file mode 100644
index 0000000..85af2b0
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/package.html
@@ -0,0 +1,117 @@
+<!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

+  -->

+<html>

+<head>

+  <title>Parser for Web Services Security Policy Language</title>

+<!--

+

+  @(#)Parser for Web Services Security Policy Language

+

+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.

+ */

+-->

+</head>

+<body bgcolor="white">

+

+This parser shows how to use the generic Policy implementation to read, process,

+and decide on policies. The generic Policy implementation provides the framework

+to read, normalize, merge, and intersect policies. The generic implementation

+follows the specifications laid down in the document 

+<a href="http://www-128.ibm.com/developerworks/webservices/library/specification/ws-polfram/">

+<i>Web Services Policy Framework</i></a>.

+<p/>

+The <i>Parser for Web Services Security Policy Language</i> uses the generic policy

+implementation to read, normalize, and merge Web Service Sercurity policy files. The

+parser then parses and processes the specific Web Services Security Policy assertions.

+The document <a href="http://www-128.ibm.com/developerworks/library/specification/ws-secpol/">

+<i>Web Services Security Policy Language</i></a> defines the specific Web Service

+Security Policy assertions.

+<p/>

+This is an example and the parser provides a skeleton for further development. Currently

+the processing methods of all assertions return <code>true</code>, that is every assertion

+is accepted.

+

+<h3>Prerequisties</h3>

+To be able to run the generic Policy implementation and the associated examples you

+need several additonal Jar files from the current Axis2 development because some

+examples use the StAX API and the OM XML datamodell implemented in Axis2. Currently

+you need

+

+<ul>

+  <li>Axis2-0.94.jar</li>

+  <li>axis2-wsdl-0.94.jar</li>

+  <li>axis2-common-0.94.jar</li>

+  <li>wsdl4j-1.5.1.jar</li>

+  <li>stax-api-1.0.jar</li>

+  <li>stax-1.1.2.jar</li>

+</ul>

+

+In addition you also need the ubiquitous log4j, junit and commons-logging jars. At least

+this is the enviroment I currently use. For the Axis2 files you may use the according

+*SNAPSHOT.jar files as well.

+

+<h3>How does it work</h3>

+The main class is <code>WSSpolicyProcessorFull</code>. At first it populates the top level

+token with all security policy tokens/assertions known at the top level. All 

+tokens/assertions are pre-initialized in the <code>SecurityPolicy</code> class file. We always

+use copies of the pre-initialized token structures. During setup the parser initializes

+the top level tokens with the objects that contain the processing methods for the

+tokens.

+<p/>

+There are two types of security policy tokens: <i>simple</i> tokens and <i>complex</i> tokens. 

+Simple tokens stand for themself and do not contains subtokens or assertions. Simple

+tokens switch on properties of define a specific behaviour. Complex token contain other

+tokens and assertions. At the top level we only have complex tokens (refer to the <code>

+setup</code> method).

+<p/>

+When the parser finds a security policy assertion (<code>PrimitiveAssertion</code>) it starts

+a policy transaction (<code>startPolicyTransaction</code>). The start policy transaction

+checks if the current token contains this assertion as a child assertin. If the parser finds the

+assertion it sets up the parser context and calls the assertion's processing function. The

+processing functions use the following naming pattern: use the token's name and prepend

+this name with the string <i>do</i>. For example: the processing method of the <i>X509Token</i>

+has the name <code>doX509Token</code>. Each processing function of a complex token

+initializes its child tokens on the first call of the processing function (lazy initialization).

+<p/>

+If all children of an assertion/token are processed the policy transaction is either committed or aborted

+depending on the outcome of the processing of the child tokens. During commit transaction

+the information gathered during the processing of the child tokens can be check, validated,

+and mixed with other data. These functions are not implemented in this example. If a transaction

+has to be aborted you can perform some cleanup.

+<p/>

+All policies are parsed recursively. If a policy containes alternatives the first alternative

+that matches or can be processed is chosen. 

+

+<h3>Missing stuff</h3>

+As noted before this is an example and provides some ideas how to implement a security

+policy parser. Not all top level tokens are implemented as processors (all assertions/tokens are

+pre-initialized in SecurityPolicy). The following processors are currently missing:

+

+<ul>

+  <li>IssuedToken</li>

+  <li>KerberosToken</li>

+  <li>SpnegoContextToken</li>

+  <li>SecurityContextToken</li>

+  <li>SecureConversationToken</li>

+  <li>SamlTokenAssertion</li>

+  <li>RelTokenAssertion</li>

+</ul>

+

+<!-- Put @see and @since tags down here. -->

+@since  Parser for Web Services Security Policy Language 1.0

+</body>

+</html>

diff --git a/src/org/apache/ws/security/policy/parser/processors/AlgorithmSuiteProcessor.java b/src/org/apache/ws/security/policy/parser/processors/AlgorithmSuiteProcessor.java
new file mode 100644
index 0000000..05190bc
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/AlgorithmSuiteProcessor.java
@@ -0,0 +1,439 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.Constants;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.AlgorithmSuite;

+import org.apache.ws.security.policy.model.AlgorithmWrapper;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class AlgorithmSuiteProcessor {

+

+    private Log log = LogFactory.getLog(getClass());

+

+    private boolean initializedAlgorithmSuite = false;

+

+    /**

+     * Intialize the AlgorithmSuite complex token.

+     * 

+     * This method creates a copy of the AlgorithmSuite token and sets the

+     * handler object to the copy. Then it creates copies of the child tokens

+     * that are allowed for AlgorithmSuite. These tokens are:

+     * 

+     * These copies are also initialized with the handler object and then set as

+     * child tokens of AlgorithmSuite.

+     * 

+     * <p/> The handler object that must contain the methods

+     * <code>doAlgorithmSuite</code>.

+     * 

+     * @param spt

+     *            The token that will hold the child tokens.

+     * @throws NoSuchMethodException

+     */

+

+    private void initializeAlgorithmSuite(SecurityPolicyToken spt)

+            throws NoSuchMethodException {

+

+        SecurityPolicyToken tmpSpt;

+

+        tmpSpt = SecurityPolicy.basic256.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic192.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic128.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.tripleDes.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic256Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic192Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic128Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.tripleDesRsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic256Sha256.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic192Sha256.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic128Sha256.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.tripleDesSha256.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic256Sha256Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic192Sha256Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.basic128Sha256Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.tripleDesSha256Rsa15.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.inclusiveC14N.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.soapNormalization10.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.strTransform10.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.xPath10.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.xPathFilter20.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+    }

+

+    public Object doAlgorithmSuite(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+        SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+        switch (spc.getAction()) {

+

+        case SecurityProcessorContext.START:

+            if (!initializedAlgorithmSuite) {

+                try {

+                    initializeAlgorithmSuite(spt);

+                    initializedAlgorithmSuite = true;

+                } catch (NoSuchMethodException e) {

+                    // TODO Auto-generated catch block

+                    e.printStackTrace();

+                    return new Boolean(false);

+                }

+            }

+            log.debug(spt.getTokenName());

+            PrimitiveAssertion pa = spc.getAssertion();

+            String text = pa.getStrValue();

+            if (text != null) {

+                text = text.trim();

+                log.debug("Value: '" + text.toString() + "'");

+            }

+        case SecurityProcessorContext.COMMIT:

+            break;

+        case SecurityProcessorContext.ABORT:

+            break;

+        }

+        return new Boolean(true);

+    }

+

+    public Object doBasic256(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic192(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic128(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doTripleDes(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic256Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic192Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic128Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doTripleDesRsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic256Sha256(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic192Sha256(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic128Sha256(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doTripleDesSha256(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic256Sha256Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic192Sha256Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doBasic128Sha256Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doTripleDesSha256Rsa15(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        return this.setAlgoGroup(spc);

+    }

+

+    public Object doInclusiveC14N(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                .readCurrentPolicyEngineData();

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                algoSuite.setC14n(Constants.C14N);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    public Object doSoapNormalization10(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                .readCurrentPolicyEngineData();

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                algoSuite.setSoapNormalization(Constants.SNT);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    public Object doStrTransform10(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                .readCurrentPolicyEngineData();

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                algoSuite.setStrTransform(Constants.STRT10);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    public Object doXPath10(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                .readCurrentPolicyEngineData();

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                algoSuite.setXPath(Constants.XPATH);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    public Object doXPathFilter20(SecurityProcessorContext spc) {

+        log

+                .debug("Processing "

+                        + spc.readCurrentSecurityToken().getTokenName()

+                        + ": "

+                        + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                .readCurrentPolicyEngineData();

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                algoSuite.setXPath(Constants.XPATH20);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    private Boolean setAlgoGroup(SecurityProcessorContext spc) {

+        if (spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                AlgorithmSuite algoSuite = (AlgorithmSuite) spc

+                        .readCurrentPolicyEngineData();

+                algoSuite.setAlgorithmSuite(spc.getAssertion().getName()

+                        .getLocalPart());

+                ((AlgorithmWrapper) spc.readPreviousPolicyEngineData())

+                        .setAlgorithmSuite(algoSuite);

+            } catch (WSSPolicyException e) {

+                log.error(e.getMessage(), e);

+                return new Boolean(false);                

+            }

+        }

+        return new Boolean(true);

+    }

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/AsymmetricBindingProcessor.java b/src/org/apache/ws/security/policy/parser/processors/AsymmetricBindingProcessor.java
new file mode 100644
index 0000000..7a37cc0
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/AsymmetricBindingProcessor.java
@@ -0,0 +1,212 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.Constants;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.Binding;

+import org.apache.ws.security.policy.model.AsymmetricBinding;

+import org.apache.ws.security.policy.model.SymmetricBinding;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class AsymmetricBindingProcessor {

+

+    private Log log = LogFactory.getLog(getClass());

+    

+    private boolean initializedAsymmetricBinding = false;

+    

+	/**

+	 * Intialize the AsymmetricBinding complex token.

+	 * 

+	 * This method creates a copy of the AsymmetricBinding token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for AsymmetricBinding. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of AsymmetricBinding.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeAsymmetricBinding(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+

+		InitiatorRecipientTokenProcessor irt = new InitiatorRecipientTokenProcessor();

+		SecurityPolicyToken tmpSpt = SecurityPolicy.initiatorToken.copy();

+		tmpSpt.setProcessTokenMethod(irt);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.recipientToken.copy();

+		tmpSpt.setProcessTokenMethod(irt);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.layout.copy();

+		tmpSpt.setProcessTokenMethod(new LayoutProcessor());

+		spt.setChildToken(tmpSpt);

+

+//		tmpSpt = SecurityPolicy.supportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.signedSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SignedSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.endorsingSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new EndorsingSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.signedEndorsingSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SignedEndorsingSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.includeTimestamp.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.encryptBeforeSigning.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.signBeforeEncrypting.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.encryptSignature.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.protectTokens.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.onlySignEntireHeadersAndBody.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doAsymmetricBinding(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedAsymmetricBinding) {

+				try {

+					initializeAsymmetricBinding(spt);

+					initializedAsymmetricBinding = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doIncludeTimestamp(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Binding)spc.readCurrentPolicyEngineData()).setIncludeTimestamp(true);

+        }

+		return new Boolean(true);

+	}

+

+    public Object doEncryptBeforeSigning(SecurityProcessorContext spc) {

+        log.debug("Processing "

+                + spc.readCurrentSecurityToken().getTokenName() + ": "

+                + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                ((AsymmetricBinding) spc.readCurrentPolicyEngineData()).setProtectionOrder(spc

+                        .getAssertion().getName().getLocalPart());

+            } catch (WSSPolicyException e) {

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+    public Object doSignBeforeEncrypting(SecurityProcessorContext spc) {

+        log.debug("Processing "

+                + spc.readCurrentSecurityToken().getTokenName() + ": "

+                + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                ((AsymmetricBinding) spc.readCurrentPolicyEngineData()).setProtectionOrder(spc

+                        .getAssertion().getName().getLocalPart());

+            } catch (WSSPolicyException e) {

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+    

+    public Object doEncryptSignature(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((AsymmetricBinding)spc.readCurrentPolicyEngineData()).setSignatureProtection(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doProtectTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((AsymmetricBinding)spc.readCurrentPolicyEngineData()).setTokenProtection(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doOnlySignEntireHeadersAndBody(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((AsymmetricBinding)spc.readCurrentPolicyEngineData()).setEntireHeaderAndBodySignatures(true);

+        }

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/EncryptedPartsElementsProcessor.java b/src/org/apache/ws/security/policy/parser/processors/EncryptedPartsElementsProcessor.java
new file mode 100644
index 0000000..9c9ce30
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/EncryptedPartsElementsProcessor.java
@@ -0,0 +1,211 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import javax.xml.namespace.QName;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.model.Header;

+import org.apache.ws.security.policy.model.PolicyEngineData;

+import org.apache.ws.security.policy.model.SignedEncryptedElements;

+import org.apache.ws.security.policy.model.SignedEncryptedParts;

+import org.apache.ws.security.policy.model.SupportingToken;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ */

+

+public class EncryptedPartsElementsProcessor {

+

+    private Log log = LogFactory.getLog(getClass());

+

+	private boolean initializedEncryptedParts = false;

+

+	private boolean initializedEncryptedElements = false;

+    

+	/**

+	 * Intialize the EncryptedParts complex token.

+	 * 

+	 * This method creates copies of the child tokens that are allowed for

+	 * SignedParts. These tokens are Body and Header. These copies are

+	 * initialized with handler object and then set as child tokens of

+	 * EncryptedParts. <p/> The handler object must define the methods

+	 * <code>doSignedParts, doBody, doHeader</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeEncryptedParts(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.body.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.header.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	/**

+	 * Intialize the EncryptedElements complex token.

+	 * 

+	 * This method creates a copy of the child token that is allowed for

+	 * EncryptedElements. The token is XPath. This copy is initialized with a

+	 * handler object and then set as child token of EncryptedElements. <p/> The

+	 * handler object must define the method <code>doXPath</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeEncryptedElements(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.xPath.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doEncryptedParts(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedEncryptedParts) {

+				try {

+					initializeEncryptedParts(spt);

+                    SignedEncryptedParts parts = (SignedEncryptedParts) spc

+                            .readCurrentPolicyEngineData();

+                    PolicyEngineData parent = spc.readPreviousPolicyEngineData();

+                    if(parent instanceof SupportingToken) {

+                        //Parent is a supporting token

+                        ((SupportingToken)parent).setEncryptedParts(parts);

+                    }

+					initializedEncryptedParts = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doEncryptedElements(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedEncryptedElements) {

+				try {

+					initializeEncryptedElements(spt);

+                    SignedEncryptedElements elements = (SignedEncryptedElements) spc

+                            .readCurrentPolicyEngineData();

+                    PolicyEngineData parent = spc

+                            .readPreviousPolicyEngineData();

+                    if (parent instanceof SupportingToken) {

+                        // Parent is a supporting token

+                        ((SupportingToken) parent).setEncryptedElements(elements);

+                    }

+					initializedEncryptedElements = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doBody(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((SignedEncryptedParts)spc.readCurrentPolicyEngineData()).setBody(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doHeader(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            //Extract the sp:Header/@Name and sp:Header/@Namespace attrs

+            //And create a Header

+            Header header = new Header();

+            header.setName(spc.getAssertion().getAttribute(new QName("Name")));

+            header.setNamespace(spc.getAssertion().getAttribute(new QName("Namespace")));

+            ((SignedEncryptedParts)spc.readCurrentPolicyEngineData()).addHeader(header);

+        }

+        

+		return new Boolean(true);

+	}

+

+	public Object doXPath(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((SignedEncryptedElements) spc.readCurrentPolicyEngineData())

+                    .addXPathExpression(spc.getAssertion().getStrValue());

+        }

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/EndorsingSupportingTokensProcessor.java b/src/org/apache/ws/security/policy/parser/processors/EndorsingSupportingTokensProcessor.java
new file mode 100644
index 0000000..87b07a3
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/EndorsingSupportingTokensProcessor.java
@@ -0,0 +1,110 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class EndorsingSupportingTokensProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+    private boolean initializedEndorsingSupportingTokens = false;

+

+	/**

+	 * Intialize the EndorsingSupportingTokens complex token.

+	 * 

+	 * This method creates a copy of the EndorsingSupportingTokens token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for EndorsingSupportingTokens. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of EndorsingSupportingTokens.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeEndorsingSupportingTokens(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.usernameToken.copy();

+		tmpSpt.setProcessTokenMethod(new UsernameTokenProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		SignedPartsElementsProcessor spep = new SignedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.signedParts.copy();

+		tmpSpt.setProcessTokenMethod(spep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.signedElements.copy();

+		tmpSpt.setProcessTokenMethod(spep);		

+		spt.setChildToken(tmpSpt);

+

+		EncryptedPartsElementsProcessor epep = new EncryptedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.encryptedParts.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.encryptedElements.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doEndorsingSupportingTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedEndorsingSupportingTokens) {

+				try {

+					initializeEndorsingSupportingTokens(spt);

+					initializedEndorsingSupportingTokens = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/InitiatorRecipientTokenProcessor.java b/src/org/apache/ws/security/policy/parser/processors/InitiatorRecipientTokenProcessor.java
new file mode 100644
index 0000000..e94abaa
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/InitiatorRecipientTokenProcessor.java
@@ -0,0 +1,141 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.model.AsymmetricBinding;

+import org.apache.ws.security.policy.model.InitiatorToken;

+import org.apache.ws.security.policy.model.RecipientToken;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class InitiatorRecipientTokenProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+    private boolean initializedInitiatorToken = false;

+

+	private boolean initializedRecipientToken = false;

+

+	/**

+	 * Intialize the InitiatorToken complex token.

+	 * 

+	 * This method creates a copy of the InitiatorToken token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for InitiatorToken. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of InitiatorToken.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeInitiatorToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+	}

+

+	/**

+	 * Intialize the RecipientToken complex token.

+	 * 

+	 * This method creates a copy of the RecipientToken token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for RecipientToken. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of RecipientToken.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeRecipientToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+	}

+

+

+	public Object doInitiatorToken(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedInitiatorToken) {

+				try {

+					initializeInitiatorToken(spt);

+                    InitiatorToken initiatorToken = (InitiatorToken)spc.readCurrentPolicyEngineData();

+                    ((AsymmetricBinding)spc.readPreviousPolicyEngineData()).setInitiatorToken(initiatorToken);

+					initializedInitiatorToken = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doRecipientToken(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedRecipientToken) {

+				try {

+					initializeRecipientToken(spt);

+                    RecipientToken recipientToken = (RecipientToken)spc.readCurrentPolicyEngineData();

+                    ((AsymmetricBinding)spc.readPreviousPolicyEngineData()).setRecipientToken(recipientToken);

+					initializedRecipientToken = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/LayoutProcessor.java b/src/org/apache/ws/security/policy/parser/processors/LayoutProcessor.java
new file mode 100644
index 0000000..3978658
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/LayoutProcessor.java
@@ -0,0 +1,177 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.Binding;

+import org.apache.ws.security.policy.model.Layout;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class LayoutProcessor {

+

+    private Log log = LogFactory.getLog(getClass());

+

+    private boolean initializedLayout = false;

+    

+	/**

+	 * Intialize the Layout complex token.

+	 * 

+	 * This method creates a copy of the Layout token and sets the handler

+	 * object to the copy. Then it creates copies of the child tokens that are

+	 * allowed for Layout. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of Layout.

+	 * 

+	 * <p/> The handler object that must contain the methods

+	 * <code>doLayout</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeLayout(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+

+		SecurityPolicyToken tmpSpt = SecurityPolicy.strict.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.lax.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.laxTsFirst.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.laxTsLast.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doLayout(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedLayout) {

+				try {

+					initializeLayout(spt);

+					initializedLayout = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doStrict(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        try {

+            if(spc.getAction() == SecurityProcessorContext.START) {

+                Layout layout = (Layout) spc.readCurrentPolicyEngineData();

+                layout.setValue(spc.getAssertion().getName().getLocalPart());

+                ((Binding)spc.readPreviousPolicyEngineData()).setLayout(layout);

+            }

+        } catch (WSSPolicyException e) {

+            log.error(e.getMessage(), e);

+            return new Boolean(false);                

+        }

+		return new Boolean(true);

+	}

+

+	public Object doLax(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        try {

+            if(spc.getAction() == SecurityProcessorContext.START) {

+                Layout layout = (Layout) spc.readCurrentPolicyEngineData();

+                layout.setValue(spc.getAssertion().getName().getLocalPart());

+                ((Binding)spc.readPreviousPolicyEngineData()).setLayout(layout);

+            }

+        } catch (WSSPolicyException e) {

+            log.error(e.getMessage(), e);

+            return new Boolean(false);                

+        }

+		return new Boolean(true);

+	}

+

+	public Object doLaxTsFirst(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        try {

+            if(spc.getAction() == SecurityProcessorContext.START) {

+                Layout layout = (Layout) spc.readCurrentPolicyEngineData();

+                layout.setValue(spc.getAssertion().getName().getLocalPart());

+                ((Binding)spc.readPreviousPolicyEngineData()).setLayout(layout);

+            }

+        } catch (WSSPolicyException e) {

+            log.error(e.getMessage(), e);

+            return new Boolean(false);                

+        }

+		return new Boolean(true);

+	}

+

+	public Object doLaxTsLast(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        try {

+            if(spc.getAction() == SecurityProcessorContext.START) {

+                Layout layout = (Layout) spc.readCurrentPolicyEngineData();

+                layout.setValue(spc.getAssertion().getName().getLocalPart());

+                ((Binding)spc.readPreviousPolicyEngineData()).setLayout(layout);

+            }

+        } catch (WSSPolicyException e) {

+            log.error(e.getMessage(), e);

+            return new Boolean(false);                

+        }

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SignEncProtectTokenProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SignEncProtectTokenProcessor.java
new file mode 100644
index 0000000..76a56bd
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SignEncProtectTokenProcessor.java
@@ -0,0 +1,199 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.ProtectionToken;

+import org.apache.ws.security.policy.model.SymmetricBinding;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class SignEncProtectTokenProcessor {

+

+	private Log log = LogFactory.getLog(getClass());

+

+	private boolean initializedSignatureToken = false;

+

+	private boolean initializedEncryptionToken = false;

+

+	private boolean initializedProtectionToken = false;

+

+	/**

+	 * Intialize the SignatureToken complex token.

+	 * 

+	 * This method creates a copy of the SignatureToken token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for SignatureToken. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SignatureToken.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSignatureToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+	}

+

+	/**

+	 * Intialize the EncryptionToken complex token.

+	 * 

+	 * This method creates a copy of the EncryptionToken token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for EncryptionToken. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SignatureToken.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeEncryptionToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+	}

+

+	/**

+	 * Intialize the ProtectionToken complex token.

+	 * 

+	 * This method creates a copy of the ProtectionToken token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for ProtectionToken. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of ProtectionToken.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeProtectionToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doSignatureToken(SecurityProcessorContext spc) {

+		log

+				.debug("Processing "

+						+ spc.readCurrentSecurityToken().getTokenName()

+						+ ": "

+						+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSignatureToken) {

+				try {

+					initializeSignatureToken(spt);

+					initializedSignatureToken = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doEncryptionToken(SecurityProcessorContext spc) {

+		log

+				.debug("Processing "

+						+ spc.readCurrentSecurityToken().getTokenName()

+						+ ": "

+						+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedEncryptionToken) {

+				try {

+					initializeEncryptionToken(spt);

+					initializedEncryptionToken = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doProtectionToken(SecurityProcessorContext spc) {

+		log

+				.debug("Processing "

+						+ spc.readCurrentSecurityToken().getTokenName()

+						+ ": "

+						+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			ProtectionToken protectionToken = (ProtectionToken) spc

+					.readCurrentPolicyEngineData();

+			try {

+				((SymmetricBinding) spc.readPreviousPolicyEngineData())

+						.setProtectionToken(protectionToken);

+			} catch (WSSPolicyException e) {

+				return new Boolean(false);

+			}

+			if (!initializedProtectionToken) {

+				try {

+					initializeProtectionToken(spt);

+					initializedProtectionToken = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SignedEndorsingSupportingTokensProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SignedEndorsingSupportingTokensProcessor.java
new file mode 100644
index 0000000..e3ab19e
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SignedEndorsingSupportingTokensProcessor.java
@@ -0,0 +1,110 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class SignedEndorsingSupportingTokensProcessor {

+

+    private Log log = LogFactory.getLog(getClass());

+    

+    private boolean initializedSignedEndorsingSupportingTokens = false;

+    

+	/**

+	 * Intialize the SignedEndorsingSupportingTokens complex token.

+	 * 

+	 * This method creates a copy of the SignedEndorsingSupportingTokens token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for SignedEndorsingSupportingTokens. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SignedEndorsingSupportingTokens.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSignedEndorsingSupportingTokens(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.usernameToken.copy();

+		tmpSpt.setProcessTokenMethod(new UsernameTokenProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		SignedPartsElementsProcessor spep = new SignedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.signedParts.copy();

+		tmpSpt.setProcessTokenMethod(spep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.signedElements.copy();

+		tmpSpt.setProcessTokenMethod(spep);		

+		spt.setChildToken(tmpSpt);

+

+		EncryptedPartsElementsProcessor epep = new EncryptedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.encryptedParts.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.encryptedElements.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doSignedEndorsingSupportingTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSignedEndorsingSupportingTokens) {

+				try {

+					initializeSignedEndorsingSupportingTokens(spt);

+					initializedSignedEndorsingSupportingTokens = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SignedPartsElementsProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SignedPartsElementsProcessor.java
new file mode 100644
index 0000000..1f4ac0a
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SignedPartsElementsProcessor.java
@@ -0,0 +1,216 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import javax.xml.namespace.QName;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.model.Header;

+import org.apache.ws.security.policy.model.PolicyEngineData;

+import org.apache.ws.security.policy.model.SignedEncryptedElements;

+import org.apache.ws.security.policy.model.SignedEncryptedParts;

+import org.apache.ws.security.policy.model.SupportingToken;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ */

+

+public class SignedPartsElementsProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedSignedParts = false;

+

+	private boolean initializedSignedElements = false;

+

+	public SignedPartsElementsProcessor() {

+	}

+

+	/**

+	 * Intialize the SignedParts complex token.

+	 * 

+	 * This method creates copies of the child tokens that are allowed for

+	 * SignedParts. These tokens are Body and Header. These copies are

+	 * initialized with handler object and then set as child tokens of

+	 * SignedParts. <p/> The handler object must define the methods

+	 * <code>doSignedParts, doBody, doHeader</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSignedParts(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.body.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.header.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	/**

+	 * Intialize the SignedElements complex token.

+	 * 

+	 * This method creates a copy of the child token that is allowed for

+	 * SignedElements. The token is XPath. This copy is initialized with a

+	 * handler object and then set as child token of SignedElements. <p/> The

+	 * handler object must define the method <code>doXPath</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSignedElements(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.xPath.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doSignedParts(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSignedParts) {

+				try {

+					initializeSignedParts(spt);

+                    SignedEncryptedParts parts = (SignedEncryptedParts) spc

+                            .readCurrentPolicyEngineData();

+                    PolicyEngineData parent = spc

+                            .readPreviousPolicyEngineData();

+                    if (parent instanceof SupportingToken) {

+                        // Parent is a supporting token

+                        ((SupportingToken) parent).setSignedParts(parts);

+                    }

+					initializedSignedParts = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doSignedElements(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSignedElements) {

+				try {

+					initializeSignedElements(spt);

+                    SignedEncryptedElements elements = (SignedEncryptedElements) spc

+                            .readCurrentPolicyEngineData();

+                    PolicyEngineData parent = spc

+                            .readPreviousPolicyEngineData();

+                    if (parent instanceof SupportingToken) {

+                        // Parent is a supporting token

+                        ((SupportingToken) parent)

+                                .setSignedElements(elements);

+                    }

+					initializedSignedElements = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doBody(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+            if(spc.getAction() == SecurityProcessorContext.START) {

+                ((SignedEncryptedParts)spc.readCurrentPolicyEngineData()).setBody(true);

+            }

+		return new Boolean(true);

+	}

+

+	public Object doHeader(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            //Extract the sp:Header/@Name and sp:Header/@Namespace attrs

+            //And create a Header

+            Header header = new Header();

+            header.setName(spc.getAssertion().getAttribute(new QName("Name")));

+            header.setNamespace(spc.getAssertion().getAttribute(new QName("Namespace")));

+            ((SignedEncryptedParts)spc.readCurrentPolicyEngineData()).addHeader(header);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doXPath(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((SignedEncryptedElements) spc.readCurrentPolicyEngineData())

+                    .addXPathExpression(spc.getAssertion().getStrValue());

+        }

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SignedSupportingTokensProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SignedSupportingTokensProcessor.java
new file mode 100644
index 0000000..62da4f6
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SignedSupportingTokensProcessor.java
@@ -0,0 +1,109 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class SignedSupportingTokensProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+    private boolean initializedSignedSupportingTokens = false;

+    

+	/**

+	 * Intialize the SignedSupportingTokens complex token.

+	 * 

+	 * This method creates a copy of the SignedSupportingTokens token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for SignedSupportingTokens. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SignedSupportingTokens.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSignedSupportingTokens(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.usernameToken.copy();

+		tmpSpt.setProcessTokenMethod(new UsernameTokenProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		SignedPartsElementsProcessor spep = new SignedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.signedParts.copy();

+		tmpSpt.setProcessTokenMethod(spep);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.signedElements.copy();

+		tmpSpt.setProcessTokenMethod(spep);

+		spt.setChildToken(tmpSpt);

+

+		EncryptedPartsElementsProcessor epep = new EncryptedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.encryptedParts.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.encryptedElements.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doSignedSupportingTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSignedSupportingTokens) {

+				try {

+					initializeSignedSupportingTokens(spt);

+					initializedSignedSupportingTokens = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SupportingTokensProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SupportingTokensProcessor.java
new file mode 100644
index 0000000..8b7e897
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SupportingTokensProcessor.java
@@ -0,0 +1,110 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class SupportingTokensProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedSupportingTokens = false;

+

+	/**

+	 * Intialize the SupportingTokens complex token.

+	 * 

+	 * This method creates a copy of the SupportingTokens token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for SupportingTokens. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SupportingTokens.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSupportingTokens(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.x509Token.copy();

+		tmpSpt.setProcessTokenMethod(new X509TokenProcessor());

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.usernameToken.copy();

+		tmpSpt.setProcessTokenMethod(new UsernameTokenProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		SignedPartsElementsProcessor spep = new SignedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.signedParts.copy();

+		tmpSpt.setProcessTokenMethod(spep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.signedElements.copy();

+		tmpSpt.setProcessTokenMethod(spep);		

+		spt.setChildToken(tmpSpt);

+

+		EncryptedPartsElementsProcessor epep = new EncryptedPartsElementsProcessor();

+		tmpSpt = SecurityPolicy.encryptedParts.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+		

+		tmpSpt = SecurityPolicy.encryptedElements.copy();

+		tmpSpt.setProcessTokenMethod(epep);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doSupportingTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSupportingTokens) {

+				try {

+					initializeSupportingTokens(spt);

+					initializedSupportingTokens = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/SymmetricBindingProcessor.java b/src/org/apache/ws/security/policy/parser/processors/SymmetricBindingProcessor.java
new file mode 100644
index 0000000..8185ff4
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/SymmetricBindingProcessor.java
@@ -0,0 +1,218 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.Binding;

+import org.apache.ws.security.policy.model.PolicyEngineData;

+import org.apache.ws.security.policy.model.SymmetricBinding;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class SymmetricBindingProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedSymmetricBinding = false;

+

+	/**

+	 * Intialize the SymmetricBinding complex token.

+	 * 

+	 * This method creates a copy of the SymmetricBinding token and sets the

+	 * handler object to the copy. Then it creates copies of the child tokens

+	 * that are allowed for SymmetricBinding. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of SymmetricBinding.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeSymmetricBinding(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+

+		SignEncProtectTokenProcessor sept = new SignEncProtectTokenProcessor();

+		SecurityPolicyToken tmpSpt = SecurityPolicy.encryptionToken.copy();

+		tmpSpt.setProcessTokenMethod(sept);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.signatureToken.copy();

+		tmpSpt.setProcessTokenMethod(sept);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.protectionToken.copy();

+		tmpSpt.setProcessTokenMethod(sept);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.algorithmSuite.copy();

+		tmpSpt.setProcessTokenMethod(new AlgorithmSuiteProcessor());

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.layout.copy();

+		tmpSpt.setProcessTokenMethod(new LayoutProcessor());

+		spt.setChildToken(tmpSpt);

+

+//		tmpSpt = SecurityPolicy.supportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.signedSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SignedSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.endorsingSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new EndorsingSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+//

+//		tmpSpt = SecurityPolicy.signedEndorsingSupportingTokens.copy();

+//		tmpSpt.setProcessTokenMethod(new SignedEndorsingSupportingTokensProcessor());

+//		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.includeTimestamp.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.encryptBeforeSigning.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+        tmpSpt = SecurityPolicy.signBeforeEncrypting.copy();

+        tmpSpt.setProcessTokenMethod(this);

+        spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.encryptSignature.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.protectTokens.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.onlySignEntireHeadersAndBody.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+	}

+

+	public Object doSymmetricBinding(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedSymmetricBinding) {

+				try {

+					initializeSymmetricBinding(spt);

+					initializedSymmetricBinding = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			break;

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doIncludeTimestamp(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Binding)spc.readCurrentPolicyEngineData()).setIncludeTimestamp(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doEncryptBeforeSigning(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                ((SymmetricBinding) spc.readCurrentPolicyEngineData()).setProtectionOrder(spc

+                        .getAssertion().getName().getLocalPart());

+            } catch (WSSPolicyException e) {

+                return new Boolean(false);

+            }

+        }

+		return new Boolean(true);

+	}

+

+    public Object doSignBeforeEncrypting(SecurityProcessorContext spc) {

+        log.debug("Processing "

+                + spc.readCurrentSecurityToken().getTokenName() + ": "

+                + SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            try {

+                ((SymmetricBinding) spc.readCurrentPolicyEngineData()).setProtectionOrder(spc

+                        .getAssertion().getName().getLocalPart());

+            } catch (WSSPolicyException e) {

+                return new Boolean(false);

+            }

+        }

+        return new Boolean(true);

+    }

+

+	public Object doEncryptSignature(SecurityProcessorContext spc) {

+	    log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {	    

+        	PolicyEngineData readCurrentPolicyEngineData = spc.readCurrentPolicyEngineData();

+        	((SymmetricBinding) readCurrentPolicyEngineData).setSignatureProtection(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doProtectTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {		

+        	((SymmetricBinding) spc.readCurrentPolicyEngineData()).setTokenProtection(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doOnlySignEntireHeadersAndBody(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+        	((SymmetricBinding) spc.readCurrentPolicyEngineData()).setEntireHeaderAndBodySignatures(true);

+        }

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/Trust10Processor.java b/src/org/apache/ws/security/policy/parser/processors/Trust10Processor.java
new file mode 100644
index 0000000..8edfef3
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/Trust10Processor.java
@@ -0,0 +1,145 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class Trust10Processor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedTrust10 = false;

+

+	/**

+	 * Intialize the Trust10 complex token.

+	 * 

+	 * This method creates a copy of the Trust10 token and sets the handler object

+	 * to the copy. Then it creates copies of the child tokens that are allowed

+	 * for Trust10. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of Trust10.

+	 * 

+	 * <p/> The handler object that must contain the methods

+	 * <code>doTrust10</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	public void initializeTrust10(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.mustSupportClientChallenge

+				.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportServerChallenge.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireClientEntropy.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireServerEntropy.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportIssuedTokens.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doTrust10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedTrust10) {

+				try {

+					initializeTrust10(spt);

+					initializedTrust10 = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+	

+	public Object doMustSupportClientChallenge(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		return new Boolean(true);

+	}

+

+	public Object doMustSupportServerChallenge(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		return new Boolean(true);

+	}

+

+	public Object doRequireClientEntropy(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		return new Boolean(true);

+	}

+

+	public Object doRequireServerEntropy(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		return new Boolean(true);

+	}

+

+	public Object doMustSupportIssuedTokens(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/UsernameTokenProcessor.java b/src/org/apache/ws/security/policy/parser/processors/UsernameTokenProcessor.java
new file mode 100644
index 0000000..92edc23
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/UsernameTokenProcessor.java
@@ -0,0 +1,132 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import javax.xml.namespace.QName;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.Constants;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.TokenWrapper;

+import org.apache.ws.security.policy.model.UsernameToken;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ */

+public class UsernameTokenProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+

+	private boolean initializedUsernameToken = false;

+

+	/**

+	 * Intialize the UsernameToken complex token.

+	 * 

+	 * This method creates copies of the child tokens that are allowed for

+	 * UsernameToken. These tokens are WssUsernameToken10 and

+	 * WssUsernameToken11. These copies are also initialized with the handler

+	 * object and then set as child tokens of UsernameToken.

+	 * 

+	 * <p/> The handler object must define the methods

+	 * <code>doWssUsernameToken10, doWssUsernameToken11</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	public void initializeUsernameToken(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+

+		SecurityPolicyToken tmpSpt = SecurityPolicy.wssUsernameToken10.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssUsernameToken11.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doUsernameToken(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedUsernameToken) {

+				try {

+					initializeUsernameToken(spt);

+                    UsernameToken unt = (UsernameToken)spc.readCurrentPolicyEngineData();

+                    

+                    //Get the includeToken attr info

+                    String includetokenUri = spc.getAssertion().getAttribute(

+                            new QName(Constants.SP_NS,

+                                    Constants.ATTR_INCLUDE_TOKEN));

+                    try {

+                        if(includetokenUri != null) { //since its optional

+                            unt.setInclusion(includetokenUri);

+                        }

+                        ((TokenWrapper)spc.readPreviousPolicyEngineData()).setToken(unt);

+                    } catch (WSSPolicyException e) {

+                        log.error(e.getMessage(), e);

+                        return new Boolean(false);

+                    }

+					initializedUsernameToken = true;

+				} catch (NoSuchMethodException e) {

+                    log.error(e.getMessage(), e);

+                    return new Boolean(false);

+				}

+			}

+			log.debug(spt.getTokenName());

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doWssUsernameToken10(SecurityProcessorContext spc) {

+		log.debug("Processing wssUsernameToken10");

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((UsernameToken)spc.readCurrentPolicyEngineData()).setUseUTProfile11(false);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssUsernameToken11(SecurityProcessorContext spc) {

+		log.debug("Processing wssUsernameToken11");

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((UsernameToken)spc.readCurrentPolicyEngineData()).setUseUTProfile11(true);

+        }

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/Wss10Processor.java b/src/org/apache/ws/security/policy/parser/processors/Wss10Processor.java
new file mode 100644
index 0000000..9776cf2
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/Wss10Processor.java
@@ -0,0 +1,148 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.model.Wss10;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class Wss10Processor {

+

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedWss10 = false;

+

+	/**

+	 * Intialize the Wss10 complex token.

+	 * 

+	 * This method creates a copy of the Wss10 token and sets the handler object

+	 * to the copy. Then it creates copies of the child tokens that are allowed

+	 * for Wss10. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of Wss10.

+	 * 

+	 * <p/> The handler object that must contain the methods

+	 * <code>doWss10</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	public void initializeWss10(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.mustSupportRefKeyIdentifier

+				.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefIssuerSerial.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefExternalUri.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefEmbeddedToken.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	

+	public Object doWss10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedWss10) {

+				try {

+					initializeWss10(spt);

+					initializedWss10 = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+	

+	public Object doMustSupportRefKeyIdentifier(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss10)spc.readCurrentPolicyEngineData()).setMustSupportRefKeyIdentifier(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doMustSupportRefIssuerSerial(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss10)spc.readCurrentPolicyEngineData()).setMustSupportRefIssuerSerial(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefExternalURI(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss10)spc.readCurrentPolicyEngineData()).setMustSupportRefExternalURI(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefEmbeddedToken(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss10)spc.readCurrentPolicyEngineData()).setMustSupportRefEmbeddedToken(true);

+        }

+        return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/Wss11Processor.java b/src/org/apache/ws/security/policy/parser/processors/Wss11Processor.java
new file mode 100644
index 0000000..62715b0
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/Wss11Processor.java
@@ -0,0 +1,189 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.model.Wss11;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ * 

+ */

+public class Wss11Processor {

+

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedWss11 = false;

+

+	/**

+	 * Intialize the Wss11 complex token.

+	 * 

+	 * This method creates a copy of the Wss11 token and sets the handler object

+	 * to the copy. Then it creates copies of the child tokens that are allowed

+	 * for Wss10. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of Wss11.

+	 * 

+	 * <p/> The handler object that must contain the methods

+	 * <code>doWss10</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	public void initializeWss11(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+		SecurityPolicyToken tmpSpt = SecurityPolicy.mustSupportRefKeyIdentifier

+				.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefIssuerSerial.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefExternalUri.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefEmbeddedToken.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefThumbprint.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.mustSupportRefEncryptedKey.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireSignatureConfirmation.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doWss11(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedWss11) {

+				try {

+					initializeWss11(spt);

+					initializedWss11 = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+	

+	public Object doMustSupportRefKeyIdentifier(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefKeyIdentifier(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefIssuerSerial(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefIssuerSerial(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefExternalURI(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefExternalURI(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefEmbeddedToken(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefEmbeddedToken(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefThumbprint(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefThumbprint(true);

+        }

+        return new Boolean(true);

+	}

+

+	public Object doMustSupportRefEncryptedKey(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setMustSupportRefEncryptedKey(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doRequireSignatureConfirmation(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((Wss11)spc.readCurrentPolicyEngineData()).setRequireSignatureConfirmation(true);

+        }

+		return new Boolean(true);

+	}

+}

diff --git a/src/org/apache/ws/security/policy/parser/processors/X509TokenProcessor.java b/src/org/apache/ws/security/policy/parser/processors/X509TokenProcessor.java
new file mode 100644
index 0000000..27fff98
--- /dev/null
+++ b/src/org/apache/ws/security/policy/parser/processors/X509TokenProcessor.java
@@ -0,0 +1,292 @@
+/*

+ * Copyright 2004,2005 The Apache Software Foundation.

+ *

+ * 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.apache.ws.security.policy.parser.processors;

+

+import javax.xml.namespace.QName;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.policy.PrimitiveAssertion;

+import org.apache.ws.security.policy.Constants;

+import org.apache.ws.security.policy.WSSPolicyException;

+import org.apache.ws.security.policy.model.TokenWrapper;

+import org.apache.ws.security.policy.model.Wss11;

+import org.apache.ws.security.policy.model.X509Token;

+import org.apache.ws.security.policy.parser.SecurityPolicy;

+import org.apache.ws.security.policy.parser.SecurityPolicyToken;

+import org.apache.ws.security.policy.parser.SecurityProcessorContext;

+

+

+/**

+ * @author Werner Dittmann (werner@apache.org)

+ */

+public class X509TokenProcessor {

+    

+    private Log log = LogFactory.getLog(getClass());

+    

+	private boolean initializedX509Token = false;

+

+	/**

+	 * Intialize the X509 complex token.

+	 * 

+	 * This method creates a copy of the X509Token token and sets the handler

+	 * object to the copy. Then it creates copies of the child tokens that are

+	 * allowed for X509Token. These tokens are:

+	 * 

+	 * These copies are also initialized with the handler object and then set as

+	 * child tokens of X509Token.

+	 * 

+	 * <p/> The handler object that must contain the methods

+	 * <code>doX509Token</code>.

+	 * 

+	 * @param spt

+	 *            The token that will hold the child tokens.

+	 * @throws NoSuchMethodException

+	 */

+	private void initializeX509Token(SecurityPolicyToken spt)

+			throws NoSuchMethodException {

+

+		SecurityPolicyToken tmpSpt = SecurityPolicy.requireKeyIdentifierReference

+				.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireIssuerSerialReference.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireEmbeddedTokenReference.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.requireThumbprintReference.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509V1Token10.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509V3Token10.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509Pkcs7Token10.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509PkiPathV1Token10.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509V1Token11.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509V3Token11.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509Pkcs7Token11.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+

+		tmpSpt = SecurityPolicy.wssX509PkiPathV1Token11.copy();

+		tmpSpt.setProcessTokenMethod(this);

+		spt.setChildToken(tmpSpt);

+	}

+

+	public Object doX509Token(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+

+		SecurityPolicyToken spt = spc.readCurrentSecurityToken();

+

+		switch (spc.getAction()) {

+

+		case SecurityProcessorContext.START:

+			if (!initializedX509Token) {

+				try {

+					initializeX509Token(spt);

+                    X509Token token = (X509Token)spc.readCurrentPolicyEngineData();

+                    //Get the includeToken attr info

+                    String includetokenUri = spc.getAssertion().getAttribute(

+                            new QName(Constants.SP_NS,

+                                    Constants.ATTR_INCLUDE_TOKEN));

+                    try {

+                        if(includetokenUri != null) { //since its optional

+                            token.setInclusion(includetokenUri);

+                        }

+                        ((TokenWrapper)spc.readPreviousPolicyEngineData()).setToken(token);

+                    } catch (WSSPolicyException e) {

+                        // TODO Throw this out

+                        e.printStackTrace();

+                    }

+					initializedX509Token = true;

+				} catch (NoSuchMethodException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+					return new Boolean(false);

+				}

+			}

+			PrimitiveAssertion pa = spc.getAssertion();

+			String text = pa.getStrValue();

+			if (text != null) {

+				text = text.trim();

+				log.debug("Value: '" + text.toString() + "'");

+			}

+		case SecurityProcessorContext.COMMIT:

+			break;

+		case SecurityProcessorContext.ABORT:

+			break;

+		}

+		return new Boolean(true);

+	}

+

+	public Object doRequireKeyIdentifierReference(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setRequireKeyIdentifierReference(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doRequireIssuerSerialReference(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setRequireIssuerSerialReference(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doRequireEmbeddedTokenReference(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setRequireEmbeddedTokenReference(true);

+        }

+		return new Boolean(true);

+	}

+

+	public Object doRequireThumbprintReference(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setRequireThumbprintReference(true);

+        }        

+		return new Boolean(true);

+	}

+

+	public Object doWssX509V1Token10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+        return new Boolean(true);

+	}

+

+	public Object doWssX509V3Token10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509Pkcs7Token10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509PkiPathV1Token10(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509V1Token11(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509V3Token11(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509Pkcs7Token11(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+	public Object doWssX509PkiPathV1Token11(SecurityProcessorContext spc) {

+		log.debug("Processing "

+				+ spc.readCurrentSecurityToken().getTokenName() + ": "

+				+ SecurityProcessorContext.ACTION_NAMES[spc.getAction()]);

+        if(spc.getAction() == SecurityProcessorContext.START) {

+            ((X509Token)spc.readCurrentPolicyEngineData()).setTokenVersionAndType(spc

+                    .getAssertion().getName().getLocalPart());

+        }

+		return new Boolean(true);

+	}

+

+}

diff --git a/src/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java b/src/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
new file mode 100644
index 0000000..9222c97
--- /dev/null
+++ b/src/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.processor;
+
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.conversation.dkalgo.AlgoFactory;
+import org.apache.ws.security.conversation.dkalgo.DerivationAlgorithm;
+import org.apache.ws.security.message.token.DerivedKeyToken;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.util.Base64;
+import org.w3c.dom.Element;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import java.util.Vector;
+
+/**
+ * The processor to process <code>wsc:DerivedKeyToken</code>.
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class DerivedKeyTokenProcessor implements Processor {
+
+    private String id;
+    private byte[] keyBytes;
+    
+    private byte[] secret;
+    private int length;
+    private int offset;
+    private byte[] nonce;
+    private String label;
+    private String algorithm;
+    
+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,
+            CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults,
+            WSSConfig config) throws WSSecurityException {
+        
+        //Deserialize the DKT
+        DerivedKeyToken dkt = new DerivedKeyToken(elem);
+        
+        this.extractSecret(wsDocInfo, dkt);
+        
+        String tempNonce = dkt.getNonce();
+        if(tempNonce == null) {
+            throw new WSSecurityException("Missing wsc:Nonce value");
+        }
+        this.nonce = Base64.decode(tempNonce);
+        
+        this.length = dkt.getLength();
+    
+        this.label = dkt.getLabel();
+        
+        this.algorithm = dkt.getAlgorithm();
+        
+        this.id = dkt.getID();
+
+        if(length > 0) {
+            this.deriveKey();
+        }
+    }
+
+    private void deriveKey() throws WSSecurityException{
+        try {
+            DerivationAlgorithm algo = AlgoFactory.getInstance(this.algorithm);
+            byte[] labelBytes = null;
+            if(label == null || (label != null && label.length() == 0)) {
+                labelBytes = ConversationConstants.DEFAULT_LABEL.getBytes("UTF-8");
+            } else {
+                labelBytes = this.label.getBytes("UTF-8");
+            }
+            
+            byte[] seed = new byte[labelBytes.length + nonce.length];
+            System.arraycopy(labelBytes, 0, seed, 0, labelBytes.length);
+            System.arraycopy(nonce, 0, seed, labelBytes.length, nonce.length);
+            
+            this.keyBytes = algo.createKey(this.secret, seed, offset, length);
+            
+        } catch (Exception e) {
+            throw new WSSecurityException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * @param wsDocInfo
+     * @param dkt
+     * @throws WSSecurityException
+     */
+    private void extractSecret(WSDocInfo wsDocInfo, DerivedKeyToken dkt)
+            throws WSSecurityException {
+        SecurityTokenReference str = dkt.getSecuityTokenReference();
+        if (str != null) {
+            Reference ref = str.getReference();
+            String uri = ref.getURI();
+            Processor processor = wsDocInfo.getProcessor(uri.substring(1));
+            if (processor instanceof EncryptedKeyProcessor) {
+                this.secret = ((EncryptedKeyProcessor) processor)
+                        .getDecryptedBytes();
+            } else if (processor instanceof SecurityContextTokenProcessor) {
+                this.secret = ((SecurityContextTokenProcessor) processor)
+                        .getSecret();
+            } else {
+                throw new WSSecurityException(
+                        WSSecurityException.FAILED_ENC_DEC, "unsupportedKeyId");
+            }
+        } else {
+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,
+                    "noReference");
+        }
+    }
+
+    /**
+     * Returns the wsu:Id of the DerivedKeyToken
+     * @see org.apache.ws.security.processor.Processor#getId()
+     */
+    public String getId() {
+        return this.id;
+    }
+
+    /**
+     * @return Returns the keyBytes.
+     */
+    public byte[] getKeyBytes() {
+        return keyBytes;
+    }
+    
+    /**
+     * Get the derived key bytes for a given length
+     * @return Returns the keyBytes.
+     */
+    public byte[] getKeyBytes(int len) throws WSSecurityException {
+        this.length = len;
+        this.deriveKey();
+        return keyBytes;
+    } 
+
+}
diff --git a/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java b/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
new file mode 100644
index 0000000..c2a1f25
--- /dev/null
+++ b/src/org/apache/ws/security/processor/EncryptedKeyProcessor.java
@@ -0,0 +1,430 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.message.token.X509Security;

+import org.apache.ws.security.util.Base64;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.encryption.XMLCipher;

+import org.apache.xml.security.encryption.XMLEncryptionException;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.w3c.dom.Text;

+

+import javax.crypto.BadPaddingException;

+import javax.crypto.Cipher;

+import javax.crypto.IllegalBlockSizeException;

+import javax.crypto.SecretKey;

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import javax.xml.namespace.QName;

+import java.io.IOException;

+import java.security.PrivateKey;

+import java.security.cert.X509Certificate;

+import java.util.Vector;

+

+public class EncryptedKeyProcessor implements Processor {

+    private static Log log = LogFactory.getLog(EncryptedKeyProcessor.class.getName());

+    private static Log tlog =

+            LogFactory.getLog("org.apache.ws.security.TIME");

+

+    private byte[] decryptedBytes = null;

+    private WSSConfig wssConfig = null;

+    private String encryptedKeyId = null;

+

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found encrypted key element");

+        }

+        wssConfig = wsc;

+        if (decCrypto == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "noDecCryptoFile");

+        }

+        if (cb == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "noCallback");

+        }

+        handleEncryptedKey((Element) elem, cb, decCrypto);

+        encryptedKeyId = elem.getAttributeNS(null, "Id");

+

+        returnResults.add(0, new WSSecurityEngineResult(WSConstants.ENCR, null, null, null, null));

+    }

+

+    public void handleEncryptedKey(Element xencEncryptedKey,

+                                   CallbackHandler cb, Crypto crypto) throws WSSecurityException {

+        handleEncryptedKey(xencEncryptedKey, cb, crypto, null);

+    }

+

+    public void handleEncryptedKey(Element xencEncryptedKey,

+                                   PrivateKey privatekey) throws WSSecurityException {

+        handleEncryptedKey(xencEncryptedKey, null, null, privatekey);

+    }

+

+    public void handleEncryptedKey(Element xencEncryptedKey,

+                                   CallbackHandler cb, Crypto crypto, PrivateKey privateKey)

+            throws WSSecurityException {

+        long t0 = 0, t1 = 0, t2 = 0;

+        if (tlog.isDebugEnabled()) {

+            t0 = System.currentTimeMillis();

+        }

+        // need to have it to find the encryped data elements in the envelope

+        Document doc = xencEncryptedKey.getOwnerDocument();

+

+        // lookup xenc:EncryptionMethod, get the Algorithm attribute to determine

+        // how the key was encrypted. Then check if we support the algorithm

+

+        Node tmpE = null;    // short living Element used for lookups only

+        tmpE = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey,

+                "EncryptionMethod", WSConstants.ENC_NS);

+        String keyEncAlgo = null;

+        if (tmpE != null) {

+            keyEncAlgo = ((Element) tmpE).getAttribute("Algorithm");

+        }

+        if (keyEncAlgo == null) {

+            throw new WSSecurityException

+                    (WSSecurityException.UNSUPPORTED_ALGORITHM, "noEncAlgo");

+        }

+        Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);

+        /*

+         * Well, we can decrypt the session (symmetric) key. Now lookup CipherValue, this is the value of the

+         * encrypted session key (session key usually is a symmetrical key that encrypts

+         * the referenced content). This is a 2-step lookup

+         */

+        Element xencCipherValue = null;

+        tmpE = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "CipherData", WSConstants.ENC_NS);

+        if (tmpE != null) {

+            xencCipherValue = (Element) WSSecurityUtil.getDirectChild((Node) tmpE,

+                    "CipherValue", WSConstants.ENC_NS);

+        }

+        if (xencCipherValue == null) {

+            throw new WSSecurityException

+                    (WSSecurityException.INVALID_SECURITY, "noCipher");

+        }

+

+        if (privateKey == null) {

+            Element keyInfo = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey,

+                    "KeyInfo", WSConstants.SIG_NS);

+            String alias;

+            if (keyInfo != null) {

+                Element secRefToken;

+                secRefToken = (Element) WSSecurityUtil.getDirectChild(keyInfo,

+                        "SecurityTokenReference", WSConstants.WSSE_NS);

+                /*

+                 * EncryptedKey must a a STR as child of KeyInfo, KeyName  

+                 * valid only for EncryptedData

+                 */

+//                if (secRefToken == null) {

+//                    secRefToken = (Element) WSSecurityUtil.getDirectChild(keyInfo,

+//                            "KeyName", WSConstants.SIG_NS);

+//                }

+                if (secRefToken == null) {

+                    throw new WSSecurityException

+                            (WSSecurityException.INVALID_SECURITY, "noSecTokRef");

+                }

+                SecurityTokenReference secRef = new SecurityTokenReference(secRefToken);

+                /*

+				 * Well, at this point there are several ways to get the key.

+				 * Try to handle all of them :-).

+				 */

+                alias = null;

+                /*

+                * handle X509IssuerSerial here. First check if all elements are available,

+                * get the appropriate data, check if all data is available.

+                * If all is ok up to that point, look up the certificate alias according

+                * to issuer name and serial number.

+                * This method is recommended by OASIS WS-S specification, X509 profile

+                */

+                if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {

+                    alias = secRef.getX509IssuerSerialAlias(crypto);

+                    if (log.isDebugEnabled()) {

+                        log.debug("X509IssuerSerial alias: " + alias);

+                    }

+                }

+                /*

+                * If wsse:KeyIdentifier found, then the public key of the attached cert was used to

+                * encrypt the session (symmetric) key that encrypts the data. Extract the certificate

+                * using the BinarySecurity token (was enhanced to handle KeyIdentifier too).

+                * This method is _not_ recommended by OASIS WS-S specification, X509 profile

+                */

+                else if (secRef.containsKeyIdentifier()) {

+                    X509Certificate[] certs = secRef.getKeyIdentifier(crypto);

+                    if (certs == null || certs.length < 1 || certs[0] == null) {

+                        throw new WSSecurityException(WSSecurityException.FAILURE,

+                                "invalidX509Data", new Object[]{"for decryption (KeyId)"});

+                    }

+                    /*

+                    * Here we have the certificate. Now find the alias for it. Needed to identify

+                    * the private key associated with this certificate

+                    */

+                    alias = crypto.getAliasForX509Cert(certs[0]);

+                    if (log.isDebugEnabled()) {

+                        log.debug("cert: " + certs[0]);

+                        log.debug("KeyIdentifier Alias: " + alias);

+                    }

+                } else if (secRef.containsReference()) {

+                    Element bstElement = secRef.getTokenElement(doc, null);

+

+                    // at this point ... check token type: Binary

+                    QName el =

+                            new QName(bstElement.getNamespaceURI(),

+                                    bstElement.getLocalName());

+                    if (el.equals(WSSecurityEngine.binaryToken)) {

+                        X509Security token = null;

+                        String value = bstElement.getAttribute(WSSecurityEngine.VALUE_TYPE);

+                        if (!X509Security.getType().equals(value)

+                                || ((token = new X509Security(bstElement)) == null)) {

+                            throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,

+                                    "unsupportedBinaryTokenType",

+                                    new Object[]{"for decryption (BST)"});

+                        }

+                        X509Certificate cert = token.getX509Certificate(crypto);

+                        if (cert == null) {

+                            throw new WSSecurityException(WSSecurityException.FAILURE,

+                                    "invalidX509Data",

+                                    new Object[]{"for decryption"});

+                        }

+                        /*

+                        * Here we have the certificate. Now find the alias for it. Needed to identify

+                        * the private key associated with this certificate

+                        */

+                        alias = crypto.getAliasForX509Cert(cert);

+                        if (log.isDebugEnabled()) {

+                            log.debug("BST Alias: " + alias);

+                        }

+                    } else {

+                        throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,

+                                "unsupportedToken",

+                                null);

+                    }

+        			/*

+        			 * The following code is somewhat strange: the called crypto method gets

+        			 * the keyname and searches for a certificate with an issuer's name that is

+        			 * equal to this keyname. No serialnumber is used - IMHO this does

+        			 * not identifies a certificate. In addition neither the WSS4J encryption

+        			 * nor signature methods use this way to identify a certificate. Because of that

+        			 * the next lines of code are disabled.  

+        			 */

+//                } else if (secRef.containsKeyName()) {

+//                    alias = crypto.getAliasForX509Cert(secRef.getKeyNameValue());

+//                    if (log.isDebugEnabled()) {

+//                        log.debug("KeyName alias: " + alias);

+//                    }

+                } else {

+                    throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");

+                }

+            } else if (crypto.getDefaultX509Alias() != null) {

+                alias = crypto.getDefaultX509Alias();

+            } else {

+                throw new WSSecurityException

+                        (WSSecurityException.INVALID_SECURITY, "noKeyinfo");

+            }

+            /*

+            * At this point we have all information necessary to decrypt the session

+            * key:

+            * - the Cipher object intialized with the correct methods

+            * - The data that holds the encrypted session key

+            * - the alias name for the private key

+            *

+            * Now use the callback here to get password that enables

+            * us to read the private key

+            */

+            WSPasswordCallback pwCb = new WSPasswordCallback(alias, WSPasswordCallback.DECRYPT);

+            Callback[] callbacks = new Callback[1];

+            callbacks[0] = pwCb;

+            try {

+                cb.handle(callbacks);

+            } catch (IOException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword",

+                        new Object[]{alias});

+            } catch (UnsupportedCallbackException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword",

+                        new Object[]{alias});

+            }

+            String password = pwCb.getPassword();

+            if (password == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword", new Object[]{alias});

+            }

+

+            try {

+                privateKey = crypto.getPrivateKey(alias, password);

+            } catch (Exception e) {

+                throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e);

+            }

+        }

+

+        try {

+            cipher.init(Cipher.DECRYPT_MODE,

+                    privateKey);

+        } catch (Exception e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);

+        }

+

+        try {

+            decryptedBytes =

+                    cipher.doFinal(getDecodedBase64EncodedData(xencCipherValue));

+        } catch (IllegalStateException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e2);

+        } catch (IllegalBlockSizeException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e2);

+        } catch (BadPaddingException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e2);

+        }

+

+        if (tlog.isDebugEnabled()) {

+            t1 = System.currentTimeMillis();

+        }

+

+        /* At this point we have the decrypted session (symmetric) key. According

+         * to W3C XML-Enc this key is used to decrypt _any_ references contained in

+         * the reference list

+         * Now lookup the references that are encrypted with this key

+         */

+        String dataRefURI = null;

+        Element refList = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey,

+                "ReferenceList", WSConstants.ENC_NS);

+        if (refList != null) {

+            for (tmpE = refList.getFirstChild();

+                 tmpE != null; tmpE = tmpE.getNextSibling()) {

+                if (tmpE.getNodeType() != Node.ELEMENT_NODE) {

+                    continue;

+                }

+                if (!tmpE.getNamespaceURI().equals(WSConstants.ENC_NS)) {

+                    continue;

+                }

+                if (tmpE.getLocalName().equals("DataReference")) {

+                    dataRefURI = ((Element) tmpE).getAttribute("URI");

+                    decryptDataRef(doc, dataRefURI, decryptedBytes);

+                }

+            }

+        }

+

+        if (tlog.isDebugEnabled()) {

+            t2 = System.currentTimeMillis();

+            tlog.debug("XMLDecrypt: total= " + (t2 - t0) +

+                    ", get-sym-key= " + (t1 - t0) +

+                    ", decrypt= " + (t2 - t1));

+        }

+        return;

+    }

+

+    /**

+     * Method getDecodedBase64EncodedData

+     *

+     * @param element

+     * @return a byte array containing the decoded data

+     * @throws WSSecurityException

+     */

+    public static byte[] getDecodedBase64EncodedData(Element element) throws WSSecurityException {

+        StringBuffer sb = new StringBuffer();

+        NodeList children = element.getChildNodes();

+        int iMax = children.getLength();

+        for (int i = 0; i < iMax; i++) {

+            Node curr = children.item(i);

+            if (curr.getNodeType() == Node.TEXT_NODE)

+                sb.append(((Text) curr).getData());

+        }

+        String encodedData = sb.toString();

+        return Base64.decode(encodedData);

+    }

+

+    private void decryptDataRef(Document doc, String dataRefURI, byte[] decryptedData) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("found data refernce: " + dataRefURI);

+        }

+        /*

+         * Look up the encrypted data. First try wsu:Id="someURI". If no such Id then

+         * try the generic lookup to find Id="someURI"

+         */

+        Element encBodyData = null;

+        if ((encBodyData = WSSecurityUtil.getElementByWsuId(doc, dataRefURI)) == null) {

+            encBodyData = WSSecurityUtil.getElementByGenId(doc, dataRefURI);

+        }

+        if (encBodyData == null) {

+            throw new WSSecurityException

+                    (WSSecurityException.INVALID_SECURITY,

+                            "dataRef", new Object[]{dataRefURI});

+        }

+

+        boolean content = X509Util.isContent(encBodyData);

+

+        // get the encryprion method

+        String symEncAlgo = X509Util.getEncAlgo(encBodyData);

+

+        SecretKey symmetricKey = WSSecurityUtil.prepareSecretKey(

+                symEncAlgo, decryptedData);

+

+        // initialize Cipher ....

+        XMLCipher xmlCipher = null;

+        try {

+            xmlCipher = XMLCipher.getInstance(symEncAlgo);

+			xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);

+		} catch (XMLEncryptionException e) {

+			throw new WSSecurityException(

+					WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e);

+		}

+

+        if (content) {

+            encBodyData = (Element) encBodyData.getParentNode();

+        }

+        try {

+            xmlCipher.doFinal(doc, encBodyData, content);

+        } catch (Exception e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC, null, null, e1);

+        }

+    }

+

+    /**

+     * Get the Id of the encrypted key element.

+     * 

+     * @return The Id string

+     */

+    public String getId() {

+    	return encryptedKeyId;

+    }

+    

+    

+    /**

+     * Get the decrypted key.

+     * 

+     * The encrypted key element contains an encrypted session key. The

+     * security functions use the session key to encrypt contents of the message

+     * with symmetrical encryption methods.

+     *  

+     * @return The decrypted key.

+     */

+    public byte[] getDecryptedBytes() {

+        return decryptedBytes;

+    }

+}

diff --git a/src/org/apache/ws/security/processor/Processor.java b/src/org/apache/ws/security/processor/Processor.java
new file mode 100644
index 0000000..d125e20
--- /dev/null
+++ b/src/org/apache/ws/security/processor/Processor.java
@@ -0,0 +1,40 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.CallbackHandler;

+import java.util.Vector;

+

+public interface Processor {

+	public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,

+			CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults,

+			WSSConfig config) throws WSSecurityException;

+	

+    /**

+     * Get the Id of the processoer.

+     * 

+     * @return The Id string

+     */

+	public String getId();

+}

diff --git a/src/org/apache/ws/security/processor/ReferenceListProcessor.java b/src/org/apache/ws/security/processor/ReferenceListProcessor.java
new file mode 100644
index 0000000..411156b
--- /dev/null
+++ b/src/org/apache/ws/security/processor/ReferenceListProcessor.java
@@ -0,0 +1,229 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import java.util.Vector;

+

+import javax.crypto.SecretKey;

+import javax.security.auth.callback.CallbackHandler;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.Reference;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.encryption.XMLCipher;

+import org.apache.xml.security.encryption.XMLEncryptionException;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+public class ReferenceListProcessor implements Processor {

+	private static Log log = LogFactory.getLog(ReferenceListProcessor.class

+			.getName());

+

+	private boolean debug = false;

+

+	WSSConfig wssConfig = null;

+

+	WSDocInfo wsDocInfo = null;

+

+	public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,

+			CallbackHandler cb, WSDocInfo wdi, Vector returnResults,

+			WSSConfig wsc) throws WSSecurityException {

+

+		debug = log.isDebugEnabled();

+		if (debug) {

+			log.debug("Found reference list element");

+		}

+		if (cb == null) {

+			throw new WSSecurityException(WSSecurityException.FAILURE,

+					"noCallback");

+		}

+		wssConfig = wsc;

+		wsDocInfo = wdi;

+		handleReferenceList((Element) elem, cb);

+		returnResults.add(0, new WSSecurityEngineResult(WSConstants.ENCR, null,

+				null, null, null));

+	}

+

+	/**

+	 * Dereferences and decodes encrypted data elements.

+	 * 

+	 * @param elem

+	 *            contains the <code>ReferenceList</code> to the encrypted

+	 *            data elements

+	 * @param cb

+	 *            the callback handler to get the key for a key name stored if

+	 *            <code>KeyInfo</code> inside the encrypted data elements

+	 */

+	private void handleReferenceList(Element elem, CallbackHandler cb)

+			throws WSSecurityException {

+

+		Document doc = elem.getOwnerDocument();

+

+		Node tmpE = null;

+		for (tmpE = elem.getFirstChild(); tmpE != null; tmpE = tmpE

+				.getNextSibling()) {

+			if (tmpE.getNodeType() != Node.ELEMENT_NODE) {

+				continue;

+			}

+			if (!tmpE.getNamespaceURI().equals(WSConstants.ENC_NS)) {

+				continue;

+			}

+			if (tmpE.getLocalName().equals("DataReference")) {

+				String dataRefURI = ((Element) tmpE).getAttribute("URI");

+				decryptDataRefEmbedded(doc, dataRefURI, cb);

+			}

+		}

+	}

+

+	public void decryptDataRefEmbedded(Document doc, String dataRefURI,

+			CallbackHandler cb) throws WSSecurityException {

+

+		if (log.isDebugEnabled()) {

+			log.debug("Found data reference: " + dataRefURI);

+		}

+		/*

+		 * Look up the encrypted data. First try wsu:Id="someURI". If no such Id

+		 * then try the generic lookup to find Id="someURI"

+		 */

+		Element encBodyData = null;

+		if ((encBodyData = WSSecurityUtil.getElementByWsuId(doc, dataRefURI)) == null) {

+			encBodyData = WSSecurityUtil.getElementByGenId(doc, dataRefURI);

+		}

+		if (encBodyData == null) {

+			throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,

+					"dataRef", new Object[] { dataRefURI });

+		}

+

+		boolean content = X509Util.isContent(encBodyData);

+

+		// Now figure out the encryption algorithm

+		String symEncAlgo = X509Util.getEncAlgo(encBodyData);

+

+		Element tmpE = (Element) WSSecurityUtil.findElement((Node) encBodyData,

+				"KeyInfo", WSConstants.SIG_NS);

+		if (tmpE == null) {

+			throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,

+					"noKeyinfo");

+		}

+

+		/*

+		 * Try to get a security reference token, if none found try to get a

+		 * shared key using a KeyName.

+		 */

+		Element secRefToken = (Element) WSSecurityUtil.getDirectChild(tmpE,

+				"SecurityTokenReference", WSConstants.WSSE_NS);

+

+		SecretKey symmetricKey = null;

+		if (secRefToken == null) {

+			symmetricKey = X509Util.getSharedKey(tmpE, symEncAlgo, cb);

+		} else

+			symmetricKey = getKeyFromReference(secRefToken, symEncAlgo);

+

+		// initialize Cipher ....

+		XMLCipher xmlCipher = null;

+		try {

+		    xmlCipher = XMLCipher.getInstance(symEncAlgo);

+			xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);

+		} catch (XMLEncryptionException e1) {

+			throw new WSSecurityException(

+					WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e1);

+		}

+

+		if (content) {

+			encBodyData = (Element) encBodyData.getParentNode();

+		}

+		try {

+			xmlCipher.doFinal(doc, encBodyData, content);

+		} catch (Exception e) {

+			throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,

+					null, null, e);

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.apache.ws.security.processor.Processor#getId()

+	 * 

+	 * A reference list does not have an id.

+	 */

+	public String getId() {

+		return null;

+	}

+

+	/**

+	 * Retrieves a secret key (session key) from a already parsed EncryptedKey

+	 * element

+	 * 

+	 * This method takes a security token reference (STR) element and checks if

+	 * it contains a Reference element. Then it gets the vale of the URI

+	 * attribute of the Reference and uses the retrieved value to lookup an

+	 * EncrypteKey element to get the decrypted session key bytes. Using the

+	 * algorithm parameter these bytes are converted into a secret key.

+	 * 

+	 * <p/>

+	 * 

+	 * This method requires that the EncyrptedKey element is already available,

+	 * thus requires a strict layout of the security header. This method

+	 * supports EncryptedKey elements within the same message.

+	 * 

+	 * @param secRefToken

+	 *            The element containg the STR

+	 * @param algorithm

+	 *            A string that identifies the symmetric decryption algorithm

+	 * @return The secret key for the specified algorithm

+	 * @throws WSSecurityException

+	 */

+	private SecretKey getKeyFromReference(Element secRefToken, String algorithm)

+			throws WSSecurityException {

+

+		SecurityTokenReference secRef = new SecurityTokenReference(secRefToken);

+		byte[] decryptedData = null;

+

+		if (secRef.containsReference()) {

+			Reference reference = secRef.getReference();

+			String uri = reference.getURI();

+			String id = uri.substring(1);

+			Processor p = wsDocInfo.getProcessor(id);

+			if (p == null || (!(p instanceof EncryptedKeyProcessor) && !(p instanceof DerivedKeyTokenProcessor))) {

+				throw new WSSecurityException(

+						WSSecurityException.FAILED_ENC_DEC, "unsupportedKeyId");

+			}

+			if(p instanceof EncryptedKeyProcessor) {

+    			EncryptedKeyProcessor ekp = (EncryptedKeyProcessor) p;

+    			decryptedData = ekp.getDecryptedBytes();

+            } else if(p instanceof DerivedKeyTokenProcessor) {

+                DerivedKeyTokenProcessor dkp = (DerivedKeyTokenProcessor) p;

+                decryptedData = dkp.getKeyBytes(WSSecurityUtil.getKeyLength(algorithm));

+            }

+		} else {

+			throw new WSSecurityException(WSSecurityException.FAILED_ENC_DEC,

+					"noReference");

+		}

+		return WSSecurityUtil.prepareSecretKey(algorithm, decryptedData);

+	}

+}

diff --git a/src/org/apache/ws/security/processor/SAMLTokenProcessor.java b/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
new file mode 100644
index 0000000..34f4417
--- /dev/null
+++ b/src/org/apache/ws/security/processor/SAMLTokenProcessor.java
@@ -0,0 +1,76 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.opensaml.SAMLAssertion;

+import org.opensaml.SAMLException;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.CallbackHandler;

+import java.util.Vector;

+

+public class SAMLTokenProcessor implements Processor {

+    private static Log log = LogFactory.getLog(SAMLTokenProcessor.class.getName());

+

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found SAML Assertion element");

+        }

+        SAMLAssertion assertion = handleSAMLToken((Element) elem);

+        wsDocInfo.setAssertion((Element) elem);

+        returnResults.add(0,

+                new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, assertion));

+

+    }

+

+    public SAMLAssertion handleSAMLToken(Element token) throws WSSecurityException {

+        boolean result = false;

+        SAMLAssertion assertion = null;

+        try {

+            assertion = new SAMLAssertion(token);

+            result = true;

+            if (log.isDebugEnabled()) {

+                log.debug("SAML Assertion issuer " + assertion.getIssuer());

+            }

+        } catch (SAMLException e) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLsecurity", null, e);

+        }

+        if (!result) {

+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);

+        }

+        return assertion;

+    }

+

+    /* (non-Javadoc)

+     * @see org.apache.ws.security.processor.Processor#getId()

+     * TODO The Id of a SAML token?

+     */

+    public String getId() {

+    	return null;

+    }

+

+}

diff --git a/src/org/apache/ws/security/processor/SecurityContextTokenProcessor.java b/src/org/apache/ws/security/processor/SecurityContextTokenProcessor.java
new file mode 100644
index 0000000..4e2bd04
--- /dev/null
+++ b/src/org/apache/ws/security/processor/SecurityContextTokenProcessor.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.processor;
+
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.SecurityContextToken;
+import org.w3c.dom.Element;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * The processor to process <code>wsc:SecurityContextToken</code>.
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class SecurityContextTokenProcessor implements Processor {
+
+    /**
+     * The <code>wsi:ID</code> of the <code>wsc:SecurityContextToken</code>
+     * element.
+     */
+    private String sctId;
+
+    /**
+     * The secret associated with the <code>wsc:SecurityContextToken</code>.
+     */
+    private byte[] secret;
+
+    /**
+     * The <code>wsc:Identifier</code> of the
+     * <code>wsc:SecurityContextToken</code> element.
+     */
+    private String identifier;
+
+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto,
+            CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults,
+            WSSConfig config) throws WSSecurityException {
+
+        SecurityContextToken sct = new SecurityContextToken(elem);
+        this.identifier = sct.getIdentifier();
+        this.secret = this.getSecret(cb, sct);
+        this.sctId = sct.getID();
+    }
+
+    /**
+     * Get the secret from the provided callback handler and return it.
+     * 
+     * @param cb
+     * @param sct
+     * @return The key collected using the callback handler
+     */
+    private byte[] getSecret(CallbackHandler cb, SecurityContextToken sct)
+            throws WSSecurityException {
+
+        if (cb == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE,
+                    "noCallback");
+        }
+
+        WSPasswordCallback callback = new WSPasswordCallback(sct
+                .getIdentifier(), WSPasswordCallback.SECURITY_CONTEXT_TOKEN);
+        Callback[] callbacks = new Callback[1];
+        callbacks[0] = callback;
+        try {
+            cb.handle(callbacks);
+        } catch (IOException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
+                    new Object[] { sct.getIdentifier() });
+        } catch (UnsupportedCallbackException e) {
+            throw new WSSecurityException(WSSecurityException.FAILURE, "noKey",
+                    new Object[] { sct.getIdentifier() });
+        }
+
+        return callback.getKey();
+    }
+
+    /**
+     * Return the id of the 
+     */
+    public String getId() {
+        return this.sctId;
+    }
+
+    /**
+     * @return Returns the identifier.
+     */
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return Returns the secret.
+     */
+    public byte[] getSecret() {
+        return secret;
+    }
+
+}
diff --git a/src/org/apache/ws/security/processor/SignatureConfirmationProcessor.java b/src/org/apache/ws/security/processor/SignatureConfirmationProcessor.java
new file mode 100644
index 0000000..9f7cc26
--- /dev/null
+++ b/src/org/apache/ws/security/processor/SignatureConfirmationProcessor.java
@@ -0,0 +1,60 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.SignatureConfirmation;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.CallbackHandler;

+import java.util.Vector;

+

+public class SignatureConfirmationProcessor implements Processor {

+    private static Log log = LogFactory.getLog(SignatureConfirmationProcessor.class.getName());

+

+    private String scId;

+    

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found SignatureConfirmation list element");

+        }

+        /*

+         * Decode SignatureConfirmation, just store in result

+         */

+        SignatureConfirmation sigConf = new SignatureConfirmation(

+                (Element) elem);

+        returnResults.add(0, new WSSecurityEngineResult(WSConstants.SC,

+                sigConf));

+        

+        scId = elem.getAttributeNS(WSConstants.WSU_NS, "Id");

+    }

+    

+    /* (non-Javadoc)

+     * @see org.apache.ws.security.processor.Processor#getId()

+     */

+    public String getId() {

+    	return scId;

+    }    

+}

diff --git a/src/org/apache/ws/security/processor/SignatureProcessor.java b/src/org/apache/ws/security/processor/SignatureProcessor.java
new file mode 100644
index 0000000..0259b75
--- /dev/null
+++ b/src/org/apache/ws/security/processor/SignatureProcessor.java
@@ -0,0 +1,392 @@
+/*

+ * Copyright  2003-2006 The Apache Software Foundation, or their licensors, as

+ * appropriate.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDerivedKeyTokenPrincipal;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSDocInfoStore;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.WSUsernameTokenPrincipal;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.EnvelopeIdResolver;

+import org.apache.ws.security.message.token.BinarySecurity;

+import org.apache.ws.security.message.token.DerivedKeyToken;

+import org.apache.ws.security.message.token.PKIPathSecurity;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.message.token.UsernameToken;

+import org.apache.ws.security.message.token.X509Security;

+import org.apache.ws.security.saml.SAMLUtil;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.exceptions.XMLSecurityException;

+

+import org.apache.xml.security.keys.KeyInfo;

+import org.apache.xml.security.signature.Reference;

+import org.apache.xml.security.signature.SignedInfo;

+import org.apache.xml.security.signature.XMLSignature;

+import org.apache.xml.security.signature.XMLSignatureException;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+import javax.xml.namespace.QName;

+import javax.security.auth.callback.CallbackHandler;

+import java.security.Principal;

+import java.security.cert.CertificateExpiredException;

+import java.security.cert.CertificateNotYetValidException;

+import java.security.cert.X509Certificate;

+import java.util.Vector;

+import java.util.HashSet;

+import java.util.Set;

+

+public class SignatureProcessor implements Processor {

+    private static Log log = LogFactory.getLog(SignatureProcessor.class.getName());

+    private static Log tlog =

+            LogFactory.getLog("org.apache.ws.security.TIME");

+    

+    private String signatureId;

+

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found signature element");

+        }

+        WSDocInfoStore.store(wsDocInfo);

+        X509Certificate[] returnCert = new X509Certificate[1];

+        Set returnElements = new HashSet();

+        byte[][] signatureValue = new byte[1][];

+        Principal lastPrincipalFound = null;

+        try {

+            lastPrincipalFound = verifyXMLSignature((Element) elem,

+                    crypto, returnCert, returnElements, signatureValue);

+        } catch (WSSecurityException ex) {

+            throw ex;

+        } finally {

+            WSDocInfoStore.delete(wsDocInfo);

+        }

+        if (lastPrincipalFound instanceof WSUsernameTokenPrincipal) {

+            returnResults.add(0, new WSSecurityEngineResult(

+                    WSConstants.UT_SIGN, lastPrincipalFound, null,

+                    returnElements, signatureValue[0]));

+

+        } else {

+            returnResults.add(0, new WSSecurityEngineResult(

+                    WSConstants.SIGN, lastPrincipalFound,

+                    returnCert[0], returnElements, signatureValue[0]));

+        }

+        signatureId = elem.getAttributeNS(null, "Id");

+    }

+

+    /**

+     * Verify the WS-Security signature.

+     * <p/>

+     * The functions at first checks if then <code>KeyInfo</code> that is

+     * contained in the signature contains standard X509 data. If yes then

+     * get the certificate data via the standard <code>KeyInfo</code> methods.

+     * <p/>

+     * Otherwise, if the <code>KeyInfo</code> info does not contain X509 data, check

+     * if we can find a <code>wsse:SecurityTokenReference</code> element. If yes, the next

+     * step is to check how to get the certificate. Two methods are currently supported

+     * here:

+     * <ul>

+     * <li> A URI reference to a binary security token contained in the <code>wsse:Security

+     * </code> header.  If the derefenced token is

+     * of the correct type the contained certificate is extracted.

+     * </li>

+     * <li> Issuer name an serial number of the certificate. In this case the method

+     * looks up the certificate in the keystore via the <code>crypto</code> parameter.

+     * </li>

+     * </ul>

+     * <p/>

+     * The methods checks is the certificate is valid and calls the

+     * {@link org.apache.xml.security.signature.XMLSignature#checkSignatureValue(X509Certificate) verfication} function.

+     *

+     * @param elem        the XMLSignature DOM Element.

+     * @param crypto      the object that implements the access to the keystore and the

+     *                    handling of certificates.

+     * @param returnCert  verifyXMLSignature stores the certificate in the first

+     *                    entry of this array. Ther caller may then further validate

+     *                    the certificate

+     * @param returnElements verifyXMLSignature adds the wsu:ID attribute values for

+     * 			     the signed elements to this Set

+     * @return the subject principal of the validated X509 certificate (the

+     *         authenticated subject). The calling function may use this

+     *         principal for further authentication or authorization.

+     * @throws WSSecurityException

+     */

+    protected Principal verifyXMLSignature(Element elem,

+                                           Crypto crypto,

+                                           X509Certificate[] returnCert,

+                                           Set returnElements,

+                                           byte[][] signatureValue)

+            throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Verify XML Signature");

+        }

+        long t0 = 0, t1 = 0, t2 = 0;

+        if (tlog.isDebugEnabled()) {

+            t0 = System.currentTimeMillis();

+        }

+

+        XMLSignature sig = null;

+        try {

+            sig = new XMLSignature(elem, null);

+        } catch (XMLSecurityException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_CHECK,

+                    "noXMLSig");

+        }

+

+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());

+

+        X509Certificate[] certs = null;

+        KeyInfo info = sig.getKeyInfo();

+        byte[] secretKey = null;

+        UsernameToken ut = null;

+        DerivedKeyToken dkt = null;

+

+        if (info != null) {

+            Node node = WSSecurityUtil.getDirectChild(info.getElement(),

+                    SecurityTokenReference.SECURITY_TOKEN_REFERENCE,

+                    WSConstants.WSSE_NS);

+            if (node == null) {

+                throw new WSSecurityException(

+                        WSSecurityException.INVALID_SECURITY,

+                        "unsupportedKeyInfo");

+            }

+            SecurityTokenReference secRef = new SecurityTokenReference((Element) node);

+

+            int docHash = elem.getOwnerDocument().hashCode();

+            /*

+                * Her we get some information about the document that is being

+                * processed, in partucular the crypto implementation, and already

+                * detected BST that may be used later during dereferencing.

+                */

+            WSDocInfo wsDocInfo = WSDocInfoStore.lookup(docHash);

+

+            if (secRef.containsReference()) {

+                Element token = secRef.getTokenElement(elem.getOwnerDocument(),

+                        wsDocInfo);

+                /*

+                     * at this point check token type: UsernameToken, Binary, SAML

+                     * Crypto required only for Binary and SAML

+                     */

+                QName el = new QName(token.getNamespaceURI(), token

+                        .getLocalName());

+                if (el.equals(WSSecurityEngine.usernameToken)) {

+                    ut = new UsernameToken(token);

+                    secretKey = ut.getSecretKey();

+                } else if(el.equals(WSSecurityEngine.DERIVED_KEY_TOKEN)) {

+                    dkt = new DerivedKeyToken(token);

+                    String id = dkt.getID();

+                    DerivedKeyTokenProcessor dktProcessor = (DerivedKeyTokenProcessor) wsDocInfo

+                            .getProcessor(id);

+                    String signatureMethodURI = sig.getSignedInfo().getSignatureMethodURI();

+                    int keyLength = WSSecurityUtil.getKeyLength(signatureMethodURI);

+                    secretKey = dktProcessor.getKeyBytes(keyLength);

+                } else {

+                    if (crypto == null) {

+                        throw new WSSecurityException(WSSecurityException.FAILURE,

+                                "noSigCryptoFile");

+                    }

+                    if (el.equals(WSSecurityEngine.binaryToken)) {

+                        certs = getCertificatesTokenReference((Element) token,

+                                crypto);

+                    } else if (el.equals(WSSecurityEngine.SAML_TOKEN)) {

+                        certs = SAMLUtil.getCertificatesFromSAML((Element) token);

+                    } else {

+                        throw new WSSecurityException(

+                                WSSecurityException.INVALID_SECURITY,

+                                "unsupportedKeyInfo", new Object[]{el

+                                .toString()});

+                    }

+                }

+            } else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {

+                certs = secRef.getX509IssuerSerial(crypto);

+            } else if (secRef.containsKeyIdentifier()) {

+                certs = secRef.getKeyIdentifier(crypto);

+            } else {

+                throw new WSSecurityException(

+                        WSSecurityException.INVALID_SECURITY,

+                        "unsupportedKeyInfo", new Object[]{node.toString()});

+            }

+        } else {

+            if (crypto == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noSigCryptoFile");

+            }

+            if (crypto.getDefaultX509Alias() != null) {

+                certs = crypto.getCertificates(crypto.getDefaultX509Alias());

+            } else {

+                throw new WSSecurityException(

+                        WSSecurityException.INVALID_SECURITY,

+                        "unsupportedKeyInfo");

+            }

+        }

+        if (tlog.isDebugEnabled()) {

+            t1 = System.currentTimeMillis();

+        }

+        if ((certs == null || certs.length == 0 || certs[0] == null) && secretKey == null) {

+            throw new WSSecurityException(WSSecurityException.FAILED_CHECK);

+        }

+        if (certs != null) {

+            try {

+                certs[0].checkValidity();

+            } catch (CertificateExpiredException e) {

+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK,

+                        "invalidCert");

+            } catch (CertificateNotYetValidException e) {

+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK,

+                        "invalidCert");

+            }

+        }

+        try {

+            boolean signatureOk = false;

+            if (certs != null) {

+                signatureOk = sig.checkSignatureValue(certs[0]);

+            } else {

+                signatureOk = sig.checkSignatureValue(sig

+                        .createSecretKey(secretKey));

+            }

+            if (signatureOk) {

+                if (tlog.isDebugEnabled()) {

+                    t2 = System.currentTimeMillis();

+                    tlog.debug("Verify: total= " + (t2 - t0)

+                            + ", prepare-cert= " + (t1 - t0) + ", verify= "

+                            + (t2 - t1));

+                }

+                signatureValue[0] = sig.getSignatureValue();

+                /*

+                     * Now dig into the Signature element to get the elements that

+                     * this Signature covers. Build the QName of these Elements and

+                     * return them to caller

+                     */

+                SignedInfo si = sig.getSignedInfo();

+                int numReferences = si.getLength();

+                Vector qvec = new Vector(numReferences);

+                for (int i = 0; i < numReferences; i++) {

+                    Reference siRef;

+                    try {

+                        siRef = si.item(i);

+                    } catch (XMLSecurityException e3) {

+                        throw new WSSecurityException(

+                                WSSecurityException.FAILED_CHECK);

+                    }

+                    String uri = siRef.getURI();

+                    Element se = WSSecurityUtil.getElementByWsuId(elem.getOwnerDocument(), uri);

+                    if (se == null) {

+                        se = WSSecurityUtil.getElementByGenId(elem

+                                .getOwnerDocument(), uri);

+                    }

+                    if (se == null) {

+                        throw new WSSecurityException(

+                                WSSecurityException.FAILED_CHECK);

+                    }

+                    returnElements.add(WSSecurityUtil.getIDfromReference(uri));                    

+                }

+                

+                if (certs != null) {

+                    returnCert[0] = certs[0];

+                    return certs[0].getSubjectDN();

+                } else if(ut != null){

+                    WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(

+                            ut.getName(), ut.isHashed());

+                    principal.setNonce(ut.getNonce());

+                    principal.setPassword(ut.getPassword());

+                    principal.setCreatedTime(ut.getCreated());

+                    return principal;

+                } else if (dkt != null) {

+                    WSDerivedKeyTokenPrincipal principal = new WSDerivedKeyTokenPrincipal(dkt.getID());

+                    principal.setNonce(dkt.getNonce());

+                    principal.setLabel(dkt.getLabel());

+                    principal.setLength(dkt.getLength());

+                    principal.setOffset(dkt.getOffset());

+                    return principal;

+                } else {

+                    throw new WSSecurityException("Cannot determine principal");

+                }

+            } else {

+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK);

+            }

+        } catch (XMLSignatureException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_CHECK);

+        }

+    }

+

+    /**

+     * Extracts the certificate(s) from the Binary Security token reference.

+     * <p/>

+     *

+     * @param elem The element containing the binary security token. This is

+     *             either X509 certificate(s) or a PKIPath.

+     * @return an array of X509 certificates

+     * @throws WSSecurityException

+     */

+    public X509Certificate[] getCertificatesTokenReference(Element elem,

+                                                           Crypto crypto)

+            throws WSSecurityException {

+        BinarySecurity token = createSecurityToken(elem);

+        if (token instanceof PKIPathSecurity) {

+            return ((PKIPathSecurity) token).getX509Certificates(false, crypto);

+        } else if (token instanceof X509Security) {

+            X509Certificate cert = ((X509Security) token).getX509Certificate(crypto);

+            X509Certificate[] certs = new X509Certificate[1];

+            certs[0] = cert;

+            return certs;

+        }

+        return null;

+    }

+

+    /**

+     * Checks the <code>element</code> and creates appropriate binary security object.

+     *

+     * @param element The XML element that contains either a <code>BinarySecurityToken

+     *                </code> or a <code>PKIPath</code> element. Other element types a not

+     *                supported

+     * @return the BinarySecurity object, either a <code>X509Security</code> or a

+     *         <code>PKIPathSecurity</code> object.

+     * @throws WSSecurityException

+     */

+    private BinarySecurity createSecurityToken(Element element) throws WSSecurityException {

+        BinarySecurity token = new BinarySecurity(element);

+        String type = token.getValueType();

+        X509Security x509 = null;

+        PKIPathSecurity pkiPath = null;

+

+        if (X509Security.getType().equals(type)) {

+            x509 = new X509Security(element);

+            return (BinarySecurity) x509;

+        } else if (PKIPathSecurity.getType().equals(type)) {

+            pkiPath = new PKIPathSecurity(element);

+            return (BinarySecurity) pkiPath;

+        }

+        throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,

+                "unsupportedBinaryTokenType", new Object[]{type});

+    }

+

+    /* (non-Javadoc)

+     * @see org.apache.ws.security.processor.Processor#getId()

+     */

+    public String getId() {

+    	return signatureId;

+    }

+

+}

diff --git a/src/org/apache/ws/security/processor/TimestampProcessor.java b/src/org/apache/ws/security/processor/TimestampProcessor.java
new file mode 100644
index 0000000..8cae4cb
--- /dev/null
+++ b/src/org/apache/ws/security/processor/TimestampProcessor.java
@@ -0,0 +1,97 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.Timestamp;

+import org.apache.ws.security.util.XmlSchemaDateFormat;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.CallbackHandler;

+import java.text.DateFormat;

+import java.util.Calendar;

+import java.util.Vector;

+

+public class TimestampProcessor implements Processor {

+    private static Log log = LogFactory.getLog(TimestampProcessor.class.getName());

+

+    private WSSConfig wssConfig = null;

+    private String tsId;

+    

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found Timestamp list element");

+        }

+        wssConfig = wsc;

+        /*

+         * Decode Timestamp, add the found time (created/expiry) to result

+         */

+        Timestamp timestamp = new Timestamp((Element) elem);

+        handleTimestamp(timestamp);

+        returnResults.add(0,

+                new WSSecurityEngineResult(WSConstants.TS,

+                        timestamp));

+        tsId = elem.getAttributeNS(WSConstants.WSU_NS, "Id");

+

+    }

+

+    public void handleTimestamp(Timestamp timestamp) throws WSSecurityException {

+		if (log.isDebugEnabled()) {

+			log.debug("Preparing to verify the timestamp");

+

+			DateFormat zulu = new XmlSchemaDateFormat();

+

+			log.debug("Current time: "

+					+ zulu.format(Calendar.getInstance().getTime()));

+			if (timestamp.getCreated() != null) {

+				log.debug("Timestamp created: "

+						+ zulu.format(timestamp.getCreated().getTime()));

+			}

+			if (timestamp.getExpires() != null) {

+				log.debug("Timestamp expires: "

+						+ zulu.format(timestamp.getExpires().getTime()));

+			}

+		}

+

+		// Validate whether the security semantics have expired

+		Calendar rightNow = Calendar.getInstance();

+		Calendar exp = timestamp.getExpires();

+		if (exp != null && wssConfig.isTimeStampStrict() && exp.before(rightNow)) {

+			throw new WSSecurityException(

+					WSSecurityException.INVALID_SECURITY,

+					"invalidTimestamp",

+					new Object[] { "The security semantics of message have expired" });

+		}

+		return;

+	}

+    

+    /* (non-Javadoc)

+     * @see org.apache.ws.security.processor.Processor#getId()

+     */

+    public String getId() {

+    	return tsId;

+    }    

+    

+}

diff --git a/src/org/apache/ws/security/processor/UsernameTokenProcessor.java b/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
new file mode 100644
index 0000000..87d36bb
--- /dev/null
+++ b/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
@@ -0,0 +1,153 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSConfig;

+import org.apache.ws.security.WSSecurityEngineResult;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.WSUsernameTokenPrincipal;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.token.UsernameToken;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.IOException;

+import java.security.Principal;

+import java.util.Vector;

+

+public class UsernameTokenProcessor implements Processor {

+    private static Log log = LogFactory.getLog(UsernameTokenProcessor.class.getName());

+

+    private String utId;

+    

+    public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb, WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {

+        if (log.isDebugEnabled()) {

+            log.debug("Found UsernameToken list element");

+        }

+        Principal lastPrincipalFound = handleUsernameToken((Element) elem, cb);

+        returnResults.add(0, new WSSecurityEngineResult(WSConstants.UT,

+                lastPrincipalFound, null, null, null));

+        utId = elem.getAttributeNS(WSConstants.WSU_NS, "Id");

+

+    }

+

+    /**

+     * Check the UsernameToken element. Depending on the password type

+     * contained in the element the processing differs. If the password type

+     * is password digest (a hashed password) then process the password

+     * commpletely here. Use the callback class to get a stored password

+     * perform hash algorithm and compare the result with the transmitted

+     * password.

+     * <p/>

+     * If the password is of type password text or any other yet unknown

+     * password type the delegate the password validation to the callback

+     * class. To do so the security engine hands over all necessary data to

+     * the callback class via the WSPasswordCallback object. To distinguish

+     * from digested usernam token the usage parameter of WSPasswordCallback

+     * is set to <code>USERNAME_TOKEN_UNKNOWN</code>

+     *

+     * @param token the DOM element that contains the UsernameToken

+     * @param cb    the refernce to the callback object

+     * @return WSUsernameTokenPrincipal that contain data that an application

+     *         may use to further validate the password/user combination.

+     * @throws WSSecurityException

+     */

+    public WSUsernameTokenPrincipal handleUsernameToken(Element token, CallbackHandler cb) throws WSSecurityException {

+        UsernameToken ut = new UsernameToken(token);

+        String user = ut.getName();

+        String password = ut.getPassword();

+        String nonce = ut.getNonce();

+        String createdTime = ut.getCreated();

+        String pwType = ut.getPasswordType();

+        if (log.isDebugEnabled()) {

+            log.debug("UsernameToken user " + user);

+            log.debug("UsernameToken password " + password);

+        }

+

+        Callback[] callbacks = new Callback[1];

+        if (ut.isHashed()) {

+            if (cb == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noCallback");

+            }

+

+            WSPasswordCallback pwCb = new WSPasswordCallback(user, WSPasswordCallback.USERNAME_TOKEN);

+            callbacks[0] = pwCb;

+            try {

+                cb.handle(callbacks);

+            } catch (IOException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword",

+                        new Object[]{user});

+            } catch (UnsupportedCallbackException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword",

+                        new Object[]{user});

+            }

+            String origPassword = pwCb.getPassword();

+            if (log.isDebugEnabled()) {

+                log.debug("UsernameToken callback password " + origPassword);

+            }

+            if (origPassword == null) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword", new Object[]{user});

+            }

+            if (nonce != null && createdTime != null) {

+                String passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);

+                if (!passDigest.equals(password)) {

+                    throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);

+                }

+            }

+        } else if (cb != null) {

+            WSPasswordCallback pwCb = new WSPasswordCallback(user, password,

+                    pwType, WSPasswordCallback.USERNAME_TOKEN_UNKNOWN);

+            callbacks[0] = pwCb;

+            try {

+                cb.handle(callbacks);

+            } catch (IOException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword", new Object[]{user});

+            } catch (UnsupportedCallbackException e) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "noPassword", new Object[]{user});

+            }

+        }

+

+        WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, ut.isHashed());

+        principal.setNonce(nonce);

+        principal.setPassword(password);

+        principal.setCreatedTime(createdTime);

+        principal.setPasswordType(pwType);

+

+        return principal;

+    }

+

+    /* (non-Javadoc)

+     * @see org.apache.ws.security.processor.Processor#getId()

+     */

+    public String getId() {

+    	return utId;

+    }    

+}

diff --git a/src/org/apache/ws/security/processor/X509Util.java b/src/org/apache/ws/security/processor/X509Util.java
new file mode 100644
index 0000000..047cad2
--- /dev/null
+++ b/src/org/apache/ws/security/processor/X509Util.java
@@ -0,0 +1,125 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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.apache.ws.security.processor;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+import javax.crypto.SecretKey;

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.IOException;

+

+public class X509Util {

+    private static Log log = LogFactory.getLog(X509Util.class.getName());

+

+    public static boolean isContent(Node encBodyData) {

+        /*

+         * Depending on the encrypted data type (Content or Element) the encBodyData either

+         * holds the element whose contents where encrypted, e.g. soapenv:Body, or the

+         * xenc:EncryptedData element (in case of Element encryption). In either case we need

+         * to get the xenc:EncryptedData element. So get it. The findElement method returns

+         * immediatly if its already the correct element.

+         * Then we can get the Type attribute.

+         */

+

+        Element tmpE = (Element) WSSecurityUtil.findElement(encBodyData,

+                "EncryptedData", WSConstants.ENC_NS);

+        String typeStr = null;

+        boolean content = true;

+        if (tmpE != null) {

+            typeStr = tmpE.getAttribute("Type");

+        }

+        if (typeStr != null) {

+            content = typeStr.equals(WSConstants.ENC_NS + "Content") ? true : false;

+        }

+        return content;

+    }

+

+    public static String getEncAlgo(Node encBodyData) throws WSSecurityException {

+        Element tmpE = (Element) WSSecurityUtil.findElement(encBodyData,

+                "EncryptionMethod", WSConstants.ENC_NS);

+

+        String symEncAlgo = null;

+        if (tmpE != null) {

+            symEncAlgo = tmpE.getAttribute("Algorithm");

+        }

+        if (symEncAlgo == null) {

+            throw new WSSecurityException

+                    (WSSecurityException.UNSUPPORTED_ALGORITHM,

+                            "noEncAlgo");

+        }

+        if (log.isDebugEnabled()) {

+            log.debug("Sym Enc Algo: " + symEncAlgo);

+        }

+        return symEncAlgo;

+    }

+

+    protected static SecretKey getSharedKey(Element keyInfoElem,

+                                            String algorithm,

+                                            CallbackHandler cb)

+            throws WSSecurityException {

+        String keyName = null;

+        Element keyNmElem =

+                (Element) WSSecurityUtil.getDirectChild(keyInfoElem,

+                        "KeyName",

+                        WSConstants.SIG_NS);

+        if (keyNmElem != null) {

+            keyNmElem.normalize();

+            Node tmpN;

+            if ((tmpN = keyNmElem.getFirstChild()) != null

+                    && tmpN.getNodeType() == Node.TEXT_NODE) {

+                keyName = tmpN.getNodeValue();

+            }

+        }

+        if (keyName == null) {

+            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,

+                    "noKeyname");

+        }

+        WSPasswordCallback pwCb = new WSPasswordCallback(

+                keyName, WSPasswordCallback.KEY_NAME);

+        Callback[] callbacks = new Callback[1];

+        callbacks[0] = pwCb;

+        try {

+            cb.handle(callbacks);

+        } catch (IOException e) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "noPassword",

+                    new Object[]{keyName});

+        } catch (UnsupportedCallbackException e) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "noPassword",

+                    new Object[]{keyName});

+        }

+        byte[] decryptedData = pwCb.getKey();

+        if (decryptedData == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "noPassword",

+                    new Object[]{keyName});

+        }

+        return WSSecurityUtil.prepareSecretKey(algorithm, decryptedData);

+    }

+

+}

diff --git a/src/org/apache/ws/security/saml/SAMLIssuer.java b/src/org/apache/ws/security/saml/SAMLIssuer.java
new file mode 100644
index 0000000..4542485
--- /dev/null
+++ b/src/org/apache/ws/security/saml/SAMLIssuer.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.saml;
+
+import org.apache.ws.security.components.crypto.Crypto;
+import org.opensaml.SAMLAssertion;
+import org.w3c.dom.Document;
+
+/**
+ * Builds a WS SAML Assertion and inserts it into the SOAP Envelope.
+ * Refer to the WS specification, SAML Token profile
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+
+public interface SAMLIssuer {
+
+    /**
+     * Creates a new <code>SAMLAssertion</code>.
+     * <p/>
+     * A complete <code>SAMLAssertion</code> is constructed.
+     *
+     * @return SAMLAssertion
+     */
+    public SAMLAssertion newAssertion();
+
+    /**
+     * @param userCrypto The userCrypto to set.
+     */
+    public void setUserCrypto(Crypto userCrypto);
+
+    /**
+     * @param username The username to set.
+     */
+    public void setUsername(String username);
+
+    /**
+     * @return Returns the issuerCrypto.
+     */
+    public Crypto getIssuerCrypto();
+
+    /**
+     * @return Returns the issuerKeyName.
+     */
+    public String getIssuerKeyName();
+
+    /**
+     * @return Returns the issuerKeyPassword.
+     */
+    public String getIssuerKeyPassword();
+
+    /**
+     * @return Returns the senderVouches.
+     */
+    public boolean isSenderVouches();
+
+    /**
+     * @param instanceDoc The instanceDoc to set.
+     */
+    public void setInstanceDoc(Document instanceDoc);
+}
diff --git a/src/org/apache/ws/security/saml/SAMLIssuerFactory.java b/src/org/apache/ws/security/saml/SAMLIssuerFactory.java
new file mode 100644
index 0000000..6f40933
--- /dev/null
+++ b/src/org/apache/ws/security/saml/SAMLIssuerFactory.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.saml;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.util.Loader;
+import org.apache.ws.security.saml.SAMLIssuer;
+
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * CryptoFactory.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public abstract class SAMLIssuerFactory {
+    private static Log log = LogFactory.getLog(SAMLIssuerFactory.class);
+    private static final String defaultSAMLClassName =
+            "org.apache.ws.security.saml.WSSSAMLIssuerImpl";
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of SAMLIssuer. This method uses the file
+     * <code>saml.properties</code> to determine which implementation to
+     * use. Thus the property <code>org.apache.ws.security.saml.issuerClass</code>
+     * must define the classname of the SAMLIssuer implementation. The file
+     * may contain other property definitions as well. These properties are
+     * handed over to the  SAMLIssuer implementation. The file
+     * <code>saml.properties</code> is loaded with the
+     * <code>Loader.getResource()</code> method.
+     * <p/>
+     *
+     * @return The SAMLIssuer implementation was defined
+     */
+    public static SAMLIssuer getInstance() {
+        return getInstance("saml.properties");
+    }
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of SAMLIssuer. The properties are handed over the the SAMLIssuer
+     * implementation. The porperties can be <code>null</code>. It is depenend on the
+     * SAMLIssuer implementation how the initialization is done in this case.
+     * <p/>
+     *
+     * @param samlClassName This is the SAMLIssuer implementation class. No default is
+     *                      provided here.
+     * @param properties    The Properties that are forwarded to the SAMLIssuer implementaion.
+     *                      These properties are dependend on the SAMLIssuer implementatin
+     * @return The SAMLIssuer implementation or null if no samlClassName was defined
+     */
+    public static SAMLIssuer getInstance(String samlClassName,
+                                         Properties properties) {
+        return loadClass(samlClassName, properties);
+    }
+
+    /**
+     * getInstance
+     * <p/>
+     * Returns an instance of SAMLIssuer. This method uses the specifed filename
+     * to load a property file. This file shall use the property
+     * <code>org.apache.ws.security.saml.issuerClass</code>
+     * to define the classname of the SAMLIssuer implementation. The file
+     * may contain other property definitions as well. These properties are
+     * handed over to the SAMLIssuer implementation. The specified file
+     * is loaded with the <code>Loader.getResource()</code> method.
+     * <p/>
+     *
+     * @param propFilename The name of the property file to load
+     * @return The SAMLIssuer implementation that was defined
+     */
+    public static SAMLIssuer getInstance(String propFilename) {
+        Properties properties = null;
+        String samlClassName = null;
+
+        if ((samlClassName == null) || (samlClassName.length() == 0)) {
+            properties = getProperties(propFilename);
+            samlClassName =
+                    properties.getProperty("org.apache.ws.security.saml.issuerClass",
+                            defaultSAMLClassName);
+        }
+        return loadClass(samlClassName, properties);
+    }
+
+    private static SAMLIssuer loadClass(String samlClassName,
+                                        Properties properties) {
+        Class samlIssuerClass = null;
+        SAMLIssuer samlIssuer = null;
+        try {
+            // instruct the class loader to load the crypto implementation
+            samlIssuerClass = Loader.loadClass(samlClassName);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(samlClassName + " Not Found");
+        }
+        log.info("Using Crypto Engine [" + samlClassName + "]");
+        try {
+            Class[] classes = new Class[]{Properties.class};
+            Constructor c = samlIssuerClass.getConstructor(classes);
+            samlIssuer =
+                    (SAMLIssuer) c.newInstance(new Object[]{properties});
+            return samlIssuer;
+        } catch (java.lang.Exception e) {
+            e.printStackTrace();
+            log.error(e);
+        }
+        try {
+            // try to instantiate the Crypto subclass
+            samlIssuer = (SAMLIssuer) samlIssuerClass.newInstance();
+            return samlIssuer;
+        } catch (java.lang.Exception e) {
+            e.printStackTrace();
+            log.error(e);
+            throw new RuntimeException(samlClassName + " cannot create instance");
+        }
+    }
+
+    /**
+     * Gets the properties for SAML issuer.
+     * The functions loads the property file via
+     * {@link Loader.getResource(String)}, thus the property file
+     * should be accesible via the classpath
+     *
+     * @param propFilename the properties file to load
+     * @return a <code>Properties</code> object loaded from the filename
+     */
+    private static Properties getProperties(String propFilename) {
+        Properties properties = new Properties();
+        try {
+            URL url = Loader.getResource(propFilename);
+            properties.load(url.openStream());
+        } catch (Exception e) {
+            log.debug("Cannot find SAML property file: " + propFilename);
+            throw new RuntimeException("SAMLIssuerFactory: Cannot load properties: " + propFilename);
+        }
+        return properties;
+    }
+}
diff --git a/src/org/apache/ws/security/saml/SAMLIssuerImpl.java b/src/org/apache/ws/security/saml/SAMLIssuerImpl.java
new file mode 100644
index 0000000..3680f4d
--- /dev/null
+++ b/src/org/apache/ws/security/saml/SAMLIssuerImpl.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.saml;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.saml.SAMLIssuer;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.keys.content.X509Data;
+import org.apache.xml.security.signature.XMLSignature;
+import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLAuthenticationStatement;
+import org.opensaml.SAMLException;
+import org.opensaml.SAMLNameIdentifier;
+import org.opensaml.SAMLStatement;
+import org.opensaml.SAMLSubject;
+import org.w3c.dom.Document;
+
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Properties;
+
+/**
+ * Builds a WS SAML Assertion and inserts it into the SOAP Envelope. Refer to
+ * the WS specification, SAML Token profile
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class SAMLIssuerImpl implements SAMLIssuer {
+
+    private static Log log = LogFactory.getLog(SAMLIssuerImpl.class.getName());
+
+    private SAMLAssertion sa = null;
+
+    private Document instanceDoc = null;
+
+    private Properties properties = null;
+
+    private Crypto issuerCrypto = null;
+    private String issuerKeyPassword = null;
+    private String issuerKeyName = null;
+
+    private boolean senderVouches = true;
+
+    private String[] confirmationMethods = new String[1];
+    private Crypto userCrypto = null;
+    private String username = null;
+
+    /**
+     * Constructor.
+     */
+    public SAMLIssuerImpl() {
+    }
+
+    public SAMLIssuerImpl(Properties prop) {
+        /*
+         * if no properties .. just return an instance, the rest will be done
+         * later or this instance is just used to handle certificate
+         * conversions in this implementatio
+         */
+        if (prop == null) {
+            return;
+        }
+        properties = prop;
+
+        String cryptoProp =
+                properties.getProperty("org.apache.ws.security.saml.issuer.cryptoProp.file");
+        if (cryptoProp != null) {
+            issuerCrypto = CryptoFactory.getInstance(cryptoProp);
+            issuerKeyName =
+                    properties.getProperty("org.apache.ws.security.saml.issuer.key.name");
+            issuerKeyPassword =
+                    properties.getProperty("org.apache.ws.security.saml.issuer.key.password");
+        }
+
+        if ("senderVouches"
+                .equals(properties.getProperty("org.apache.ws.security.saml.confirmationMethod"))) {
+            confirmationMethods[0] = SAMLSubject.CONF_SENDER_VOUCHES;
+        } else if (
+                "keyHolder".equals(properties.getProperty("org.apache.ws.security.saml.confirmationMethod"))) {
+            confirmationMethods[0] = SAMLSubject.CONF_HOLDER_KEY;
+            senderVouches = false;
+        } else {
+            // throw something here - this is a mandatory property
+        }
+    }
+
+    /**
+     * Creates a new <code>SAMLAssertion</code>.
+     * <p/>
+     * <p/>
+     * A complete <code>SAMLAssertion</code> is constructed.
+     *
+     * @return SAMLAssertion
+     */
+    public SAMLAssertion newAssertion() { // throws Exception {
+        log.debug("Begin add SAMLAssertion token...");
+
+        /*
+         * if (senderVouches == false && userCrypto == null) { throw
+         * exception("need user crypto data to insert key") }
+         */
+        // Issuer must enable crypto fubctions to get the issuer's certificate
+        String issuer =
+                properties.getProperty("org.apache.ws.security.saml.issuer");
+        String name =
+                properties.getProperty("org.apache.ws.security.saml.subjectNameId.name");
+        String qualifier =
+                properties.getProperty("org.apache.ws.security.saml.subjectNameId.qualifier");
+        try {
+            SAMLNameIdentifier nameId =
+                    new SAMLNameIdentifier(name, qualifier, "");
+            String subjectIP = null;
+            String authMethod = null;
+            if ("password"
+                    .equals(properties.getProperty("org.apache.ws.security.saml.authenticationMethod"))) {
+                authMethod =
+                        SAMLAuthenticationStatement.AuthenticationMethod_Password;
+            }
+            Date authInstant = new Date();
+            Collection bindings = null;
+
+            SAMLSubject subject =
+                    new SAMLSubject(nameId,
+                            Arrays.asList(confirmationMethods),
+                            null,
+                            null);
+            SAMLStatement[] statements =
+                    {
+                        new SAMLAuthenticationStatement(subject,
+                                authMethod,
+                                authInstant,
+                                subjectIP,
+                                null,
+                                bindings)};
+            sa =
+                    new SAMLAssertion(issuer,
+                            null,
+                            null,
+                            null,
+                            null,
+                            Arrays.asList(statements));
+
+            if (!senderVouches) {
+                KeyInfo ki = new KeyInfo(instanceDoc);
+                try {
+                    X509Certificate[] certs =
+                            userCrypto.getCertificates(username);
+                    X509Data certElem = new X509Data(instanceDoc);
+                    certElem.addCertificate(certs[0]);
+                    ki.add(certElem);
+                } catch (WSSecurityException e) {
+                    return null;
+                } catch (XMLSecurityException e) {
+                    return null;
+                }
+                subject.setKeyInfo(ki);
+                // prepare to sign the SAML token
+                try {
+                    X509Certificate[] issuerCerts =
+                            issuerCrypto.getCertificates(issuerKeyName);
+
+                    String sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
+                    String pubKeyAlgo =
+                            issuerCerts[0].getPublicKey().getAlgorithm();
+                    log.debug("automatic sig algo detection: " + pubKeyAlgo);
+                    if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+                        sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+                    }
+                    java.security.Key issuerPK =
+                            issuerCrypto.getPrivateKey(issuerKeyName,
+                                    issuerKeyPassword);
+                    sa.sign(sigAlgo, issuerPK, Arrays.asList(issuerCerts));
+                } catch (WSSecurityException e1) {
+                    e1.printStackTrace();
+                    return null;
+                } catch (Exception e1) {
+                    e1.printStackTrace();
+                    return null;
+                }
+            }
+        } catch (SAMLException ex) {
+            ex.printStackTrace();
+            throw new RuntimeException(ex.toString());
+        }
+        return sa;
+    }
+
+    /**
+     * @param userCrypto The userCrypto to set.
+     */
+    public void setUserCrypto(Crypto userCrypto) {
+        this.userCrypto = userCrypto;
+    }
+
+    /**
+     * @param username The username to set.
+     */
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    /**
+     * @return Returns the issuerCrypto.
+     */
+    public Crypto getIssuerCrypto() {
+        return issuerCrypto;
+    }
+
+    /**
+     * @return Returns the issuerKeyName.
+     */
+    public String getIssuerKeyName() {
+        return issuerKeyName;
+    }
+
+    /**
+     * @return Returns the issuerKeyPassword.
+     */
+    public String getIssuerKeyPassword() {
+        return issuerKeyPassword;
+    }
+
+    /**
+     * @return Returns the senderVouches.
+     */
+    public boolean isSenderVouches() {
+        return senderVouches;
+    }
+
+    /**
+     * @param instanceDoc The instanceDoc to set.
+     */
+    public void setInstanceDoc(Document instanceDoc) {
+        this.instanceDoc = instanceDoc;
+    }
+}
diff --git a/src/org/apache/ws/security/saml/SAMLUtil.java b/src/org/apache/ws/security/saml/SAMLUtil.java
new file mode 100644
index 0000000..5a6fbd0
--- /dev/null
+++ b/src/org/apache/ws/security/saml/SAMLUtil.java
@@ -0,0 +1,123 @@
+package org.apache.ws.security.saml;

+

+import org.w3c.dom.Element;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.keys.KeyInfo;

+import org.apache.xml.security.keys.content.X509Data;

+import org.apache.xml.security.keys.content.x509.XMLX509Certificate;

+import org.apache.xml.security.exceptions.XMLSecurityException;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.opensaml.SAMLAssertion;

+import org.opensaml.SAMLException;

+import org.opensaml.SAMLSubjectStatement;

+import org.opensaml.SAMLObject;

+import org.opensaml.SAMLSubject;

+

+import java.security.cert.X509Certificate;

+import java.util.Iterator;

+

+/**

+ * Utility methods for SAML stuff

+ */

+public class SAMLUtil {

+    private static Log log = LogFactory.getLog(SAMLUtil.class.getName());

+

+    /**

+     * Extracts the certificate(s) from the SAML token reference.

+     * <p/>

+     *

+     * @param elem The element containing the SAML token.

+     * @return an array of X509 certificates

+     * @throws org.apache.ws.security.WSSecurityException

+     */

+    public static X509Certificate[] getCertificatesFromSAML(Element elem)

+            throws WSSecurityException {

+

+        /*

+         * Get some information about the SAML token content. This controls how

+         * to deal with the whole stuff. First get the Authentication statement

+         * (includes Subject), then get the _first_ confirmation method only.

+         */

+        SAMLAssertion assertion;

+        try {

+            assertion = new SAMLAssertion(elem);

+        } catch (SAMLException e) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLToken", new Object[]{"for Signature (cannot parse)"});

+        }

+        SAMLSubjectStatement samlSubjS = null;

+        Iterator it = assertion.getStatements();

+        while (it.hasNext()) {

+            SAMLObject so = (SAMLObject) it.next();

+            if (so instanceof SAMLSubjectStatement) {

+                samlSubjS = (SAMLSubjectStatement) so;

+                break;

+            }

+        }

+        SAMLSubject samlSubj = null;

+        if (samlSubjS != null) {

+            samlSubj = samlSubjS.getSubject();

+        }

+        if (samlSubj == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLToken", new Object[]{"for Signature (no Subject)"});

+        }

+

+//        String confirmMethod = null;

+//        it = samlSubj.getConfirmationMethods();

+//        if (it.hasNext()) {

+//            confirmMethod = (String) it.next();

+//        }

+//        boolean senderVouches = false;

+//        if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {

+//            senderVouches = true;

+//        }

+        Element e = samlSubj.getKeyInfo();

+        X509Certificate[] certs = null;

+        try {

+            KeyInfo ki = new KeyInfo(e, null);

+

+            if (ki.containsX509Data()) {

+                X509Data data = ki.itemX509Data(0);

+                XMLX509Certificate certElem = null;

+                if (data != null && data.containsCertificate()) {

+                    certElem = data.itemCertificate(0);

+                }

+                if (certElem != null) {

+                    X509Certificate cert = certElem.getX509Certificate();

+                    certs = new X509Certificate[1];

+                    certs[0] = cert;

+                }

+            }

+            // TODO: get alias name for cert, check against username set by caller

+        } catch (XMLSecurityException e3) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLsecurity",

+                    new Object[]{"cannot get certificate (key holder)"});

+        }

+        return certs;

+    }

+

+    public static String getAssertionId(Element envelope, String elemName, String nmSpace) throws WSSecurityException {

+        String id;

+        // Make the AssertionID the wsu:Id and the signature reference the same

+        SAMLAssertion assertion;

+

+        Element assertionElement = (Element) WSSecurityUtil

+                .findElement(envelope, elemName, nmSpace);

+

+        try {

+            assertion = new SAMLAssertion(assertionElement);

+            id = assertion.getId();

+        } catch (Exception e1) {

+            log.error(e1);

+            throw new WSSecurityException(

+                    WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig", null, e1);

+        }

+        return id;

+    }

+

+}

diff --git a/src/org/apache/ws/security/saml/WSSecSignatureSAML.java b/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
new file mode 100644
index 0000000..b148212
--- /dev/null
+++ b/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
@@ -0,0 +1,583 @@
+package org.apache.ws.security.saml;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSDocInfoStore;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.EnvelopeIdResolver;

+import org.apache.ws.security.message.WSSecHeader;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.token.Reference;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.message.token.X509Security;

+import org.apache.ws.security.transform.STRTransform;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.algorithms.SignatureAlgorithm;

+import org.apache.xml.security.exceptions.XMLSecurityException;

+import org.apache.xml.security.keys.KeyInfo;

+import org.apache.xml.security.keys.content.X509Data;

+import org.apache.xml.security.keys.content.x509.XMLX509Certificate;

+import org.apache.xml.security.signature.XMLSignature;

+import org.apache.xml.security.signature.XMLSignatureException;

+import org.apache.xml.security.transforms.TransformationException;

+import org.apache.xml.security.transforms.Transforms;

+import org.apache.xml.security.transforms.params.InclusiveNamespaces;

+import org.apache.xml.security.utils.Constants;

+import org.apache.xml.security.utils.XMLUtils;

+import org.opensaml.SAMLAssertion;

+import org.opensaml.SAMLException;

+import org.opensaml.SAMLObject;

+import org.opensaml.SAMLSubject;

+import org.opensaml.SAMLSubjectStatement;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import java.security.cert.X509Certificate;

+import java.util.Iterator;

+import java.util.Set;

+import java.util.Vector;

+

+public class WSSecSignatureSAML extends WSSecSignature {

+

+    private static Log log = LogFactory.getLog(WSSecSignatureSAML.class

+            .getName());

+

+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");

+

+    private boolean senderVouches = false;

+

+    private SecurityTokenReference secRefSaml = null;

+

+    private Element samlToken = null;

+

+    private Crypto userCrypto = null;

+

+    private Crypto issuerCrypto = null;

+

+    private String issuerKeyName = null;

+

+    private String issuerKeyPW = null;

+

+    /**

+     * Constructor.

+     */

+    public WSSecSignatureSAML() {

+    }

+

+    /**

+     * Builds a signed soap envelope with SAML token.

+     * 

+     * <p/>

+     * 

+     * The method first gets an appropriate security header. According to the

+     * defined parameters for certificate handling the signature elements are

+     * constructed and inserted into the <code>wsse:Signature</code>

+     * 

+     * @param doc

+     *            The unsigned SOAP envelope as <code>Document</code>

+     * @param assertion

+     *            the complete SAML assertion

+     * @param issuerCrypto

+     *            An instance of the Crypto API to handle keystore SAML token

+     *            issuer and to generate certificates

+     * @param issuerKeyName

+     *            Private key to use in case of "sender-Vouches"

+     * @param issuerKeyPW

+     *            Password for issuer private key

+     * @return A signed SOAP envelope as <code>Document</code>

+     * @throws org.apache.ws.security.WSSecurityException

+     */

+    public Document build(Document doc, Crypto uCrypto,

+            SAMLAssertion assertion, Crypto iCrypto, String iKeyName,

+            String iKeyPW, WSSecHeader secHeader) throws WSSecurityException {

+

+        Element securityHeader = secHeader.getSecurityHeader();

+

+        prepare(doc, uCrypto, assertion, iCrypto, iKeyName, iKeyPW, secHeader);

+

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc

+                .getDocumentElement());

+

+        if (parts == null) {

+            parts = new Vector();

+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+                    .getBodyQName().getLocalPart(), soapConstants

+                    .getEnvelopeURI(), "Content");

+            parts.add(encP);

+        }

+        addReferencesToSign(parts, secHeader);

+

+        /*

+         * The order to prepend is: - signature Element - BinarySecurityToken

+         * (depends on mode) - SecurityTokenRefrence (depends on mode) - SAML

+         * token

+         */

+

+        prependToHeader(secHeader);

+

+        /*

+         * if we have a BST prepend it in front of the Signature according to

+         * strict layout rules.

+         */

+        if (bstToken != null) {

+            prependBSTElementToHeader(secHeader);

+        }

+

+        prependSAMLElementsToHeader(secHeader);

+

+        computeSignature();

+

+        return doc;

+    }

+

+    /**

+     * Initialize a WSSec SAML Signature.

+     * 

+     * The method sets up and initializes a WSSec SAML Signature structure after

+     * the relevant information was set. After setup of the references to

+     * elements to sign may be added. After all references are added they can be

+     * signed.

+     * 

+     * <p/>

+     * 

+     * This method does not add the Signature element to the security header.

+     * See <code>prependSignatureElementToHeader()</code> method.

+     * 

+     * @param doc

+     *            The SOAP envelope as <code>Document</code>

+     * @param cr

+     *            An instance of the Crypto API to handle keystore and

+     *            certificates

+     * @param secHeader

+     *            The security header that will hold the Signature. This ise use

+     *            to construct namespace prefixes for Signature. This method

+     * @throws WSSecurityException

+     */

+    public void prepare(Document doc, Crypto uCrypto, SAMLAssertion assertion,

+            Crypto iCrypto, String iKeyName, String iKeyPW,

+            WSSecHeader secHeader) throws WSSecurityException {

+

+        doDebug = log.isDebugEnabled();

+        if (doDebug) {

+            log.debug("Beginning ST signing...");

+        }

+

+        userCrypto = uCrypto;

+        issuerCrypto = iCrypto;

+        document = doc;

+        issuerKeyName = iKeyName;

+        issuerKeyPW = iKeyPW;

+

+        /*

+         * Get some information about the SAML token content. This controls how

+         * to deal with the whole stuff. First get the Authentication statement

+         * (includes Subject), then get the _first_ confirmation method only

+         * thats if "senderVouches" is true.

+         */

+        SAMLSubjectStatement samlSubjS = null;

+        Iterator it = assertion.getStatements();

+        while (it.hasNext()) {

+            SAMLObject so = (SAMLObject) it.next();

+            if (so instanceof SAMLSubjectStatement) {

+                samlSubjS = (SAMLSubjectStatement) so;

+                break;

+            }

+        }

+        SAMLSubject samlSubj = null;

+        if (samlSubjS != null) {

+            samlSubj = samlSubjS.getSubject();

+        }

+        if (samlSubj == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLToken", new Object[] { "for Signature" });

+        }

+

+        String confirmMethod = null;

+        it = samlSubj.getConfirmationMethods();

+        if (it.hasNext()) {

+            confirmMethod = (String) it.next();

+        }

+        if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {

+            senderVouches = true;

+        }

+        /*

+         * Gather some info about the document to process and store it for

+         * retrival

+         */

+        wsDocInfo = new WSDocInfo(doc.hashCode());

+

+        X509Certificate[] certs = null;

+

+        if (senderVouches) {

+            certs = issuerCrypto.getCertificates(issuerKeyName);

+            wsDocInfo.setCrypto(issuerCrypto);

+        }

+        /*

+         * in case of key holder: - get the user's certificate that _must_ be

+         * included in the SAML token. To ensure the cert integrity the SAML

+         * token must be signed (by the issuer). Just check if its signed, but

+         * don't verify this SAML token's signature here (maybe later).

+         */

+        else {

+            if (userCrypto == null || assertion.isSigned() == false) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "invalidSAMLsecurity",

+                        new Object[] { "for SAML Signature (Key Holder)" });

+            }

+            Element e = samlSubj.getKeyInfo();

+            try {

+                KeyInfo ki = new KeyInfo(e, null);

+

+                if (ki.containsX509Data()) {

+                    X509Data data = ki.itemX509Data(0);

+                    XMLX509Certificate certElem = null;

+                    if (data != null && data.containsCertificate()) {

+                        certElem = data.itemCertificate(0);

+                    }

+                    if (certElem != null) {

+                        X509Certificate cert = certElem.getX509Certificate();

+                        certs = new X509Certificate[1];

+                        certs[0] = cert;

+                    }

+                }

+                // TODO: get alias name for cert, check against username set by

+                // caller

+            } catch (XMLSecurityException e3) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "invalidSAMLsecurity",

+                        new Object[] { "cannot get certificate (key holder)" },

+                        e3);

+            }

+            wsDocInfo.setCrypto(userCrypto);

+        }

+        if (certs == null || certs.length <= 0) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidX509Data", new Object[] { "for Signature" });

+        }

+        if (sigAlgo == null) {

+            String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();

+            log.debug("automatic sig algo detection: " + pubKeyAlgo);

+            if (pubKeyAlgo.equalsIgnoreCase("DSA")) {

+                sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;

+            } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {

+                sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;

+            } else {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILURE,

+                        "invalidX509Data",

+                        new Object[] { "for Signature - unkown public key Algo" });

+            }

+        }

+        sig = null;

+        if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {

+            Element canonElem = XMLUtils.createElementInSignatureSpace(doc,

+                    Constants._TAG_CANONICALIZATIONMETHOD);

+

+            canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);

+

+            if (wssConfig.isWsiBSPCompliant()) {

+                Set prefixes = getInclusivePrefixes(secHeader

+                        .getSecurityHeader(), false);

+

+                InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(

+                        doc, prefixes);

+

+                canonElem.appendChild(inclusiveNamespaces.getElement());

+            }

+            try {

+                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(

+                        doc, sigAlgo);

+                sig = new XMLSignature(doc, null, signatureAlgorithm

+                        .getElement(), canonElem);

+            } catch (XMLSecurityException e) {

+                log.error("", e);

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");

+            }

+        } else {

+            try {

+                sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);

+            } catch (XMLSecurityException e) {

+                log.error("", e);

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig");

+            }

+        }

+

+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());

+        String sigUri = "Signature-" + sig.hashCode();

+        sig.setId(sigUri);

+

+        keyInfo = sig.getKeyInfo();

+        keyInfoUri = "KeyId-" + keyInfo.hashCode();

+        keyInfo.setId(keyInfoUri);

+

+        secRef = new SecurityTokenReference(doc);

+        strUri = "STRId-" + secRef.hashCode();

+        secRef.setID(strUri);

+

+        certUri = "CertId-" + certs[0].hashCode();

+

+        /*

+         * If the sender vouches, then we must sign the SAML token _and_ at

+         * least one part of the message (usually the SOAP body). To do so we

+         * need to - put in a reference to the SAML token. Thus we create a STR

+         * and insert it into the wsse:Security header - set a reference of the

+         * created STR to the signature and use STR Transfrom during the

+         * signature

+         */

+        Transforms transforms = null;

+

+        try {

+            if (senderVouches) {

+                secRefSaml = new SecurityTokenReference(doc);

+                String strSamlUri = "STRSAMLId-" + secRefSaml.hashCode();

+                secRefSaml.setID(strSamlUri);

+

+                // Decouple Reference/KeyInfo setup - quick shot here

+                Reference ref = new Reference(doc);

+                ref.setURI("#" + assertion.getId());

+                ref.setValueType(WSConstants.WSS_SAML_NS

+                        + WSConstants.WSS_SAML_ASSERTION);

+                secRefSaml.setReference(ref);

+                // up to here

+

+                Element ctx = createSTRParameter(doc);

+                transforms = new Transforms(doc);

+                transforms.addTransform(STRTransform.implementedTransformURI,

+                        ctx);

+                sig.addDocument("#" + strSamlUri, transforms);

+            }

+        } catch (TransformationException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig", null, e1);

+        } catch (XMLSignatureException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig", null, e1);

+        }

+

+        switch (keyIdentifierType) {

+        case WSConstants.BST_DIRECT_REFERENCE:

+            Reference ref = new Reference(doc);

+            if (senderVouches) {

+                ref.setURI("#" + certUri);

+                bstToken = new X509Security(doc);

+                ((X509Security) bstToken).setX509Certificate(certs[0]);

+                bstToken.setID(certUri);

+                wsDocInfo.setBst(bstToken.getElement());

+                ref.setValueType(bstToken.getValueType());

+            } else {

+                ref.setURI("#" + assertion.getId());

+                ref.setValueType(WSConstants.WSS_SAML_NS

+                        + WSConstants.WSS_SAML_ASSERTION);

+            }

+            secRef.setReference(ref);

+            break;

+        //

+        // case WSConstants.ISSUER_SERIAL :

+        // XMLX509IssuerSerial data =

+        // new XMLX509IssuerSerial(doc, certs[0]);

+        // secRef.setX509IssuerSerial(data);

+        // break;

+        //

+        // case WSConstants.X509_KEY_IDENTIFIER :

+        // secRef.setKeyIdentifier(certs[0]);

+        // break;

+        //

+        // case WSConstants.SKI_KEY_IDENTIFIER :

+        // secRef.setKeyIdentifierSKI(certs[0], crypto);

+        // break;

+        //

+        default:

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "unsupportedKeyId");

+        }

+

+        keyInfo.addUnknownElement(secRef.getElement());

+

+        try {

+            samlToken = (Element) assertion.toDOM(doc);

+        } catch (SAMLException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noSAMLdoc", null, e2);

+        }

+        wsDocInfo.setAssertion(samlToken);

+    }

+

+    /**

+     * Prepend the SAML elements to the elements already in the Security header.

+     * 

+     * The method can be called any time after <code>prepare()</code>. This

+     * allows to insert the SAML elements at any position in the Security

+     * header.

+     * 

+     * <p/>

+     * 

+     * This methods first prepends the SAML security reference if mode is

+     * <code>senderVouches</code>, then the SAML token itself,

+     * 

+     * @param secHeader

+     *            The security header that holds the BST element.

+     */

+    public void prependSAMLElementsToHeader(WSSecHeader secHeader) {

+        if (senderVouches) {

+            WSSecurityUtil.prependChildElement(document, secHeader

+                    .getSecurityHeader(), secRefSaml.getElement(), true);

+        }

+

+        WSSecurityUtil.prependChildElement(document, secHeader

+                .getSecurityHeader(), samlToken, true);

+    }

+

+    /**

+     * This method adds references to the Signature.

+     * 

+     * The added references are signed when calling

+     * <code>computeSignature()</code>. This method can be called several

+     * times to add references as required. <code>addReferencesToSign()</code>

+     * can be called anytime after <code>prepare</code>.

+     * 

+     * @param references

+     *            A vector containing <code>WSEncryptionPart</code> objects

+     *            that define the parts to sign.

+     * @param secHeader

+     *            Used to compute namespaces to be inserted by

+     *            InclusiveNamespaces to be WSI compliant.

+     * @throws WSSecurityException

+     */

+    public void addReferencesToSign(Vector references, WSSecHeader secHeader)

+            throws WSSecurityException {

+        Transforms transforms = null;

+

+        Element envelope = document.getDocumentElement();

+        for (int part = 0; part < parts.size(); part++) {

+            WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);

+

+            String idToSign = encPart.getId();

+

+            String elemName = encPart.getName();

+            String nmSpace = encPart.getNamespace();

+

+            /*

+             * Set up the elements to sign. There are two resevered element

+             * names: "Token" and "STRTransform" "Token": Setup the Signature to

+             * either sign the information that points to the security token or

+             * the token itself. If its a direct reference sign the token,

+             * otherwise sign the KeyInfo Element. "STRTransform": Setup the

+             * ds:Reference to use STR Transform

+             * 

+             */

+            transforms = new Transforms(document);

+            try {

+                if (idToSign != null) {

+                    Element toSignById = WSSecurityUtil.findElementById(

+                            document.getDocumentElement(), idToSign,

+                            WSConstants.WSU_NS);

+                    if (toSignById == null) {

+                        toSignById = WSSecurityUtil.findElementById(document

+                                .getDocumentElement(), idToSign, null);

+                    }

+                    transforms

+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

+                    if (wssConfig.isWsiBSPCompliant()) {

+                        transforms.item(0).getElement().appendChild(

+                                new InclusiveNamespaces(document,

+                                        getInclusivePrefixes(toSignById))

+                                        .getElement());

+                    }

+                    sig.addDocument("#" + idToSign, transforms);

+                } else if (elemName.equals("Token")) {

+                    transforms

+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

+                    if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {

+                        if (wssConfig.isWsiBSPCompliant()) {

+                            transforms.item(0).getElement().appendChild(

+                                    new InclusiveNamespaces(document,

+                                            getInclusivePrefixes(secHeader

+                                                    .getSecurityHeader()))

+                                            .getElement());

+                        }

+                        sig.addDocument("#" + certUri, transforms);

+                    } else {

+                        if (wssConfig.isWsiBSPCompliant()) {

+                            transforms.item(0).getElement().appendChild(

+                                    new InclusiveNamespaces(document,

+                                            getInclusivePrefixes(keyInfo

+                                                    .getElement()))

+                                            .getElement());

+                        }

+                        sig.addDocument("#" + keyInfoUri, transforms);

+                    }

+                } else if (elemName.equals("STRTransform")) { // STRTransform

+                    Element ctx = createSTRParameter(document);

+                    transforms.addTransform(

+                            STRTransform.implementedTransformURI, ctx);

+                    sig.addDocument("#" + strUri, transforms);

+                } else {

+                    Element body = (Element) WSSecurityUtil.findElement(

+                            envelope, elemName, nmSpace);

+                    if (body == null) {

+                        throw new WSSecurityException(

+                                WSSecurityException.FAILURE, "noEncElement",

+                                new Object[] { nmSpace + ", " + elemName });

+                    }

+                    transforms

+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

+                    if (wssConfig.isWsiBSPCompliant()) {

+                        transforms.item(0).getElement().appendChild(

+                                new InclusiveNamespaces(document,

+                                        getInclusivePrefixes(body))

+                                        .getElement());

+                    }

+                    sig.addDocument("#" + setWsuId(body), transforms);

+                }

+            } catch (TransformationException e1) {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,

+                        e1);

+            } catch (XMLSignatureException e1) {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,

+                        e1);

+            }

+        }

+    }

+

+    /**

+     * Compute the Signature over the references.

+     * 

+     * After references are set this method computes the Signature for them.

+     * This method can be called anytime after the references were set. See

+     * <code>addReferencesToSign()</code>.

+     * 

+     * @throws WSSecurityException

+     */

+    public void computeSignature() throws WSSecurityException {

+

+        WSDocInfoStore.store(wsDocInfo);

+

+        try {

+            if (senderVouches) {

+                sig

+                        .sign(issuerCrypto.getPrivateKey(issuerKeyName,

+                                issuerKeyPW));

+            } else {

+                sig.sign(userCrypto.getPrivateKey(user, password));

+            }

+            signatureValue = sig.getSignatureValue();

+        } catch (XMLSignatureException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    null, null, e1);

+        } catch (Exception e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    null, null, e1);

+        } finally {

+            WSDocInfoStore.delete(wsDocInfo);

+        }

+    }

+}

diff --git a/src/org/apache/ws/security/saml/WSSignSAMLEnvelope.java b/src/org/apache/ws/security/saml/WSSignSAMLEnvelope.java
new file mode 100644
index 0000000..46c90a6
--- /dev/null
+++ b/src/org/apache/ws/security/saml/WSSignSAMLEnvelope.java
@@ -0,0 +1,428 @@
+package org.apache.ws.security.saml;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSDocInfo;

+import org.apache.ws.security.WSDocInfoStore;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSSecurityException;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.message.EnvelopeIdResolver;

+import org.apache.ws.security.message.WSSecHeader;

+import org.apache.ws.security.message.WSSignEnvelope;

+import org.apache.ws.security.message.token.BinarySecurity;

+import org.apache.ws.security.message.token.Reference;

+import org.apache.ws.security.message.token.SecurityTokenReference;

+import org.apache.ws.security.message.token.X509Security;

+import org.apache.ws.security.transform.STRTransform;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.xml.security.exceptions.XMLSecurityException;

+import org.apache.xml.security.keys.KeyInfo;

+import org.apache.xml.security.keys.content.X509Data;

+import org.apache.xml.security.keys.content.x509.XMLX509Certificate;

+import org.apache.xml.security.signature.XMLSignature;

+import org.apache.xml.security.signature.XMLSignatureException;

+import org.apache.xml.security.transforms.TransformationException;

+import org.apache.xml.security.transforms.Transforms;

+import org.opensaml.SAMLAssertion;

+import org.opensaml.SAMLException;

+import org.opensaml.SAMLObject;

+import org.opensaml.SAMLSubject;

+import org.opensaml.SAMLSubjectStatement;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import java.security.cert.X509Certificate;

+import java.util.Iterator;

+import java.util.Vector;

+

+public class WSSignSAMLEnvelope extends WSSignEnvelope {

+

+    private static Log log = LogFactory.getLog(WSSignSAMLEnvelope.class

+            .getName());

+

+    private static Log tlog = LogFactory.getLog("org.apache.ws.security.TIME");

+

+    /**

+     * Constructor.

+     * 

+     * @deprecated replaced by {@link WSSecSignatureSAML#constructor()}

+     */

+    public WSSignSAMLEnvelope() {

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param actor

+     *            The actor name of the <code>wsse:Security</code> header

+     * @param mu

+     *            Set <code>mustUnderstand</code> to true or false

+     * 

+     * @deprecated replaced by {@link WSSecSignatureSAML#constructor()} and

+     *             {@link WSSecHeader} for actor and mustunderstand

+     *             specification.

+     */

+    public WSSignSAMLEnvelope(String actor, boolean mu) {

+        super(actor, mu);

+    }

+

+    /**

+     * Builds a signed soap envelope with SAML token. <p/>The method first gets

+     * an appropriate security header. According to the defined parameters for

+     * certificate handling the signature elements are constructed and inserted

+     * into the <code>wsse:Signature</code>

+     * 

+     * @param doc

+     *            The unsigned SOAP envelope as <code>Document</code>

+     * @param assertion

+     *            the complete SAML assertion

+     * @param issuerCrypto

+     *            An instance of the Crypto API to handle keystore SAML token

+     *            issuer and to generate certificates

+     * @param issuerKeyName

+     *            Private key to use in case of "sender-Vouches"

+     * @param issuerKeyPW

+     *            Password for issuer private key

+     * @return A signed SOAP envelope as <code>Document</code>

+     * @throws org.apache.ws.security.WSSecurityException

+     * @deprecated replaced by

+     *             {@link WSSecSignatureSAML#build(Document, Crypto, SAMLAssertion, Crypto, String, String, WSSecHeader)}

+     */

+    public Document build(Document doc, Crypto userCrypto,

+            SAMLAssertion assertion, Crypto issuerCrypto, String issuerKeyName,

+            String issuerKeyPW) throws WSSecurityException {

+

+        doDebug = log.isDebugEnabled();

+

+        long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;

+        if (tlog.isDebugEnabled()) {

+            t0 = System.currentTimeMillis();

+        }

+        if (doDebug) {

+            log.debug("Beginning ST signing...");

+        }

+        /*

+         * Get some information about the SAML token content. This controls how

+         * to deal with the whole stuff. First get the Authentication statement

+         * (includes Subject), then get the _first_ confirmation method only.

+         */

+        SAMLSubjectStatement samlSubjS = null;

+        Iterator it = assertion.getStatements();

+        while (it.hasNext()) {

+            SAMLObject so = (SAMLObject) it.next();

+            if (so instanceof SAMLSubjectStatement) {

+                samlSubjS = (SAMLSubjectStatement) so;

+                break;

+            }

+        }

+        SAMLSubject samlSubj = null;

+        if (samlSubjS != null) {

+            samlSubj = samlSubjS.getSubject();

+        }

+        if (samlSubj == null) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidSAMLToken", new Object[] { "for Signature" });

+        }

+

+        String confirmMethod = null;

+        it = samlSubj.getConfirmationMethods();

+        if (it.hasNext()) {

+            confirmMethod = (String) it.next();

+        }

+        boolean senderVouches = false;

+        if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {

+            senderVouches = true;

+        }

+        /*

+         * Gather some info about the document to process and store it for

+         * retrival

+         */

+        WSDocInfo wsDocInfo = new WSDocInfo(doc.hashCode());

+

+        Element envelope = doc.getDocumentElement();

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

+

+        Element securityHeader = insertSecurityHeader(doc);

+        X509Certificate[] certs = null;

+

+        if (senderVouches) {

+            certs = issuerCrypto.getCertificates(issuerKeyName);

+            wsDocInfo.setCrypto(issuerCrypto);

+        }

+        /*

+         * in case of key holder: - get the user's certificate that _must_ be

+         * included in the SAML token. To ensure the cert integrity the SAML

+         * token must be signed (by the issuer). Just check if its signed, but

+         * don't verify this SAML token's signature here (maybe later).

+         */

+        else {

+            if (userCrypto == null || assertion.isSigned() == false) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "invalidSAMLsecurity",

+                        new Object[] { "for SAML Signature (Key Holder)" });

+            }

+            Element e = samlSubj.getKeyInfo();

+            try {

+                KeyInfo ki = new KeyInfo(e, null);

+

+                if (ki.containsX509Data()) {

+                    X509Data data = ki.itemX509Data(0);

+                    XMLX509Certificate certElem = null;

+                    if (data != null && data.containsCertificate()) {

+                        certElem = data.itemCertificate(0);

+                    }

+                    if (certElem != null) {

+                        X509Certificate cert = certElem.getX509Certificate();

+                        certs = new X509Certificate[1];

+                        certs[0] = cert;

+                    }

+                }

+                // TODO: get alias name for cert, check against username set by

+                // caller

+            } catch (XMLSecurityException e3) {

+                throw new WSSecurityException(WSSecurityException.FAILURE,

+                        "invalidSAMLsecurity",

+                        new Object[] { "cannot get certificate (key holder)" },

+                        e3);

+            }

+            wsDocInfo.setCrypto(userCrypto);

+        }

+        // Set the id of the elements to be used as digest source

+        // String id = setBodyID(doc);

+        if (certs == null || certs.length <= 0) {

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "invalidX509Data", new Object[] { "for Signature" });

+        }

+        if (sigAlgo == null) {

+            String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();

+            log.debug("automatic sig algo detection: " + pubKeyAlgo);

+            if (pubKeyAlgo.equalsIgnoreCase("DSA")) {

+                sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;

+            } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {

+                sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;

+            } else {

+                throw new WSSecurityException(

+                        WSSecurityException.FAILURE,

+                        "invalidX509Data",

+                        new Object[] { "for Signature - unkown public key Algo" });

+            }

+        }

+        XMLSignature sig = null;

+        try {

+            sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);

+        } catch (XMLSecurityException e) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig");

+        }

+

+        KeyInfo info = sig.getKeyInfo();

+        String keyInfoUri = "KeyId-" + info.hashCode();

+        info.setId(keyInfoUri);

+

+        SecurityTokenReference secRef = new SecurityTokenReference(doc);

+        String strUri = "STRId-" + secRef.hashCode();

+        secRef.setID(strUri);

+

+        String certUri = "CertId-" + certs[0].hashCode();

+

+        if (tlog.isDebugEnabled()) {

+            t1 = System.currentTimeMillis();

+        }

+

+        if (parts == null) {

+            parts = new Vector();

+            WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+                    .getBodyQName().getLocalPart(), soapConstants

+                    .getEnvelopeURI(), "Content");

+            parts.add(encP);

+        }

+

+        /*

+         * If the sender vouches, then we must sign the SAML token _and_ at

+         * least one part of the message (usually the SOAP body). To do so we

+         * need to - put in a reference to the SAML token. Thus we create a STR

+         * and insert it into the wsse:Security header - set a reference of the

+         * created STR to the signature and use STR Transfrom during the

+         * signature

+         */

+        Transforms transforms = null;

+        SecurityTokenReference secRefSaml = null;

+

+        try {

+            if (senderVouches) {

+                secRefSaml = new SecurityTokenReference(doc);

+                String strSamlUri = "STRSAMLId-" + secRefSaml.hashCode();

+                secRefSaml.setID(strSamlUri);

+                // Decouple Refernce/KeyInfo setup - quick shot here

+                Reference ref = new Reference(doc);

+                ref.setURI("#" + assertion.getId());

+                ref.setValueType(WSConstants.WSS_SAML_NS

+                        + WSConstants.WSS_SAML_ASSERTION);

+                secRefSaml.setReference(ref);

+                // up to here

+                Element ctx = createSTRParameter(doc);

+                transforms = new Transforms(doc);

+                transforms.addTransform(STRTransform.implementedTransformURI,

+                        ctx);

+                sig.addDocument("#" + strSamlUri, transforms);

+            }

+            for (int part = 0; part < parts.size(); part++) {

+                WSEncryptionPart encPart = (WSEncryptionPart) parts.get(part);

+                String elemName = encPart.getName();

+                String nmSpace = encPart.getNamespace();

+

+                /*

+                 * Set up the elements to sign. There are two resevered element

+                 * names: "Token" and "STRTransform" "Token": Setup the

+                 * Signature to either sign the information that points to the

+                 * security token or the token itself. If its a direct reference

+                 * sign the token, otherwise sign the KeyInfo Element.

+                 * "STRTransform": Setup the ds:Reference to use STR Transform

+                 * 

+                 */

+                if (elemName.equals("Token")) {

+                    transforms = new Transforms(doc);

+                    transforms

+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

+                    if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {

+                        sig.addDocument("#" + certUri, transforms);

+                    } else {

+                        sig.addDocument("#" + keyInfoUri, transforms);

+                    }

+                } else if (elemName.equals("STRTransform")) { // STRTransform

+                    Element ctx = createSTRParameter(doc);

+                    transforms = new Transforms(doc);

+                    transforms.addTransform(

+                            STRTransform.implementedTransformURI, ctx);

+                    sig.addDocument("#" + strUri, transforms);

+                } else {

+                    Element body = (Element) WSSecurityUtil.findElement(

+                            envelope, elemName, nmSpace);

+                    if (body == null) {

+                        throw new WSSecurityException(

+                                WSSecurityException.FAILURE, "noEncElement",

+                                new Object[] { nmSpace + ", " + elemName });

+                    }

+                    transforms = new Transforms(doc);

+                    transforms

+                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

+                    sig.addDocument("#" + setWsuId(body), transforms);

+                }

+            }

+        } catch (TransformationException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig", null, e1);

+        } catch (XMLSignatureException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noXMLSig", null, e1);

+        }

+

+        sig.addResourceResolver(EnvelopeIdResolver.getInstance());

+

+        /*

+         * The order to prepend is: - signature - BinarySecurityToken (depends

+         * on mode) - SecurityTokenRefrence (depends on mode) - SAML token

+         */

+

+        WSSecurityUtil.prependChildElement(doc, securityHeader, sig

+                .getElement(), false);

+

+        if (tlog.isDebugEnabled()) {

+            t2 = System.currentTimeMillis();

+        }

+        switch (keyIdentifierType) {

+        case WSConstants.BST_DIRECT_REFERENCE:

+            Reference ref = new Reference(doc);

+            if (senderVouches) {

+                ref.setURI("#" + certUri);

+                BinarySecurity bstToken = null;

+                bstToken = new X509Security(doc);

+                ((X509Security) bstToken).setX509Certificate(certs[0]);

+                bstToken.setID(certUri);

+                WSSecurityUtil.prependChildElement(doc, securityHeader,

+                        bstToken.getElement(), false);

+                wsDocInfo.setBst(bstToken.getElement());

+                ref.setValueType(bstToken.getValueType());

+            } else {

+                ref.setURI("#" + assertion.getId());

+                ref.setValueType(WSConstants.WSS_SAML_NS

+                        + WSConstants.WSS_SAML_ASSERTION);

+            }

+            secRef.setReference(ref);

+            break;

+        //

+        // case WSConstants.ISSUER_SERIAL :

+        // XMLX509IssuerSerial data =

+        // new XMLX509IssuerSerial(doc, certs[0]);

+        // secRef.setX509IssuerSerial(data);

+        // break;

+        //

+        // case WSConstants.X509_KEY_IDENTIFIER :

+        // secRef.setKeyIdentifier(certs[0]);

+        // break;

+        //

+        // case WSConstants.SKI_KEY_IDENTIFIER :

+        // secRef.setKeyIdentifierSKI(certs[0], crypto);

+        // break;

+        //

+        default:

+            throw new WSSecurityException(WSSecurityException.FAILURE,

+                    "unsupportedKeyId");

+        }

+

+        if (tlog.isDebugEnabled()) {

+            t3 = System.currentTimeMillis();

+        }

+        info.addUnknownElement(secRef.getElement());

+

+        Element samlToken = null;

+        try {

+            samlToken = (Element) assertion.toDOM(doc);

+        } catch (SAMLException e2) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    "noSAMLdoc", null, e2);

+        }

+        if (senderVouches) {

+            WSSecurityUtil.prependChildElement(doc, securityHeader, secRefSaml

+                    .getElement(), true);

+        }

+

+        wsDocInfo.setAssertion(samlToken);

+        WSSecurityUtil

+                .prependChildElement(doc, securityHeader, samlToken, true);

+

+        WSDocInfoStore.store(wsDocInfo);

+        try {

+            if (senderVouches) {

+                sig

+                        .sign(issuerCrypto.getPrivateKey(issuerKeyName,

+                                issuerKeyPW));

+            } else {

+                sig.sign(userCrypto.getPrivateKey(user, password));

+            }

+            signatureValue = sig.getSignatureValue();

+        } catch (XMLSignatureException e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    null, null, e1);

+        } catch (Exception e1) {

+            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,

+                    null, null, e1);

+        } finally {

+            WSDocInfoStore.delete(wsDocInfo);

+        }

+        if (tlog.isDebugEnabled()) {

+            t4 = System.currentTimeMillis();

+            tlog.debug("SignEnvelope: cre-Sig= " + (t1 - t0)

+                    + " set transform= " + (t2 - t1) + " sec-ref= " + (t3 - t2)

+                    + " signature= " + (t4 - t3));

+        }

+        if (doDebug) {

+            log.debug("Signing complete.");

+        }

+        return (doc);

+

+    }

+}

diff --git a/src/org/apache/ws/security/saml/saml.properties b/src/org/apache/ws/security/saml/saml.properties
new file mode 100644
index 0000000..f8492e9
--- /dev/null
+++ b/src/org/apache/ws/security/saml/saml.properties
@@ -0,0 +1,10 @@
+org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.WSSSAMLIssuerImpl
+org.apache.ws.security.saml.issuerCryptoProp.file=crypto.properties
+org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
+org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
+org.apache.ws.security.saml.authenticationMethod=password
+org.apache.ws.security.saml.confirmationMethod=senderVouches
+#org.apache.ws.security.saml.confirmationMethod=keyHolder
+#org.apache.ws.security.saml
+#org.apache.ws.security.saml
diff --git a/src/org/apache/ws/security/transform/STRTransform.java b/src/org/apache/ws/security/transform/STRTransform.java
new file mode 100644
index 0000000..cbe6af9
--- /dev/null
+++ b/src/org/apache/ws/security/transform/STRTransform.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.transform;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSDocInfoStore;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.c14n.CanonicalizationException;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.c14n.InvalidCanonicalizerException;
+import org.apache.xml.security.signature.XMLSignatureInput;
+import org.apache.xml.security.transforms.TransformSpi;
+import org.apache.ws.security.util.Base64;
+import org.apache.xml.security.utils.XMLUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+/**
+ * Class STRTransform
+ * 
+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)
+ * @version 1.0
+ */
+public class STRTransform extends TransformSpi {
+
+    /**
+     * Field implementedTransformURI
+     */
+    public static final String implementedTransformURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform";
+
+    private static Log log = LogFactory.getLog(STRTransform.class.getName());
+
+    private static boolean doDebug = false;
+
+    private static String FAKE_NS = "urn:X";
+
+    private static String XMLNS = "xmlns=";
+
+    private WSDocInfo wsDocInfo = null;
+
+    public boolean wantsOctetStream() {
+        return false;
+    }
+
+    public boolean wantsNodeSet() {
+        return true;
+    }
+
+    public boolean returnsOctetStream() {
+        return true;
+    }
+
+    public boolean returnsNodeSet() {
+        return false;
+    }
+
+    /**
+     * Method engineGetURI
+     */
+    protected String engineGetURI() {
+        return STRTransform.implementedTransformURI;
+    }
+
+    /**
+     * Method enginePerformTransform
+     * 
+     * @param input
+     * @throws CanonicalizationException
+     * @throws InvalidCanonicalizerException
+     */
+    protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
+            throws IOException, CanonicalizationException,
+            InvalidCanonicalizerException {
+
+        doDebug = log.isDebugEnabled();
+
+        if (doDebug) {
+            log.debug("Beginning STRTransform..." + input.toString());
+        }
+
+        try {
+
+            /*
+             * Get the main document, that is the complete SOAP request document
+             */
+            Document thisDoc = this._transformObject.getDocument();
+            int docHash = thisDoc.hashCode();
+            if (doDebug) {
+                log.debug("doc: " + thisDoc.toString() + ", " + docHash);
+            }
+
+            /*
+             * Here we get some information about the document that is being
+             * processed, in partucular the crypto implementation, and already
+             * detected BST that may be used later during dereferencing.
+             */
+            wsDocInfo = WSDocInfoStore.lookup(docHash);
+            if (wsDocInfo == null) {
+                throw (new CanonicalizationException("no WSDocInfo found"));
+            }
+
+            /*
+             * According to the OASIS WS Specification "Web Services Security:
+             * SOAP Message Security 1.0" Monday, 19 January 2004, chapter 8.3
+             * describes that the input node set must be processed bythe c14n
+             * that is specified in the argument element of the STRTransform
+             * element.
+             * 
+             * First step: Get the required c14n argument and get the specified
+             * Canonicalizer
+             */
+
+            String canonAlgo = null;
+            if (this._transformObject.length(WSConstants.WSSE_NS,
+                    "TransformationParameters") == 1) {
+                Element tmpE = XMLUtils.selectNode(this._transformObject
+                        .getElement().getFirstChild(), WSConstants.WSSE_NS,
+                        "TransformationParameters", 0);
+                Element canonElem = (Element) WSSecurityUtil.getDirectChild(
+                        tmpE, "CanonicalizationMethod", WSConstants.SIG_NS);
+                canonAlgo = canonElem.getAttribute("Algorithm");
+                if (doDebug) {
+                    log.debug("CanonAlgo: " + canonAlgo);
+                }
+            }
+            Canonicalizer canon = Canonicalizer.getInstance(canonAlgo);
+
+            ByteArrayOutputStream bos = null;
+            byte[] buf = null;
+            if (doDebug) {
+                buf = input.getBytes();
+                bos = new ByteArrayOutputStream(buf.length);
+                bos.write(buf, 0, buf.length);
+                log.debug("canon bos: " + bos.toString());
+            }
+
+            /*
+             * Get the input (node) to transform. Currently we support only an
+             * Element as input format. If other formats are required we must
+             * get it as bytes and probably reparse it into a DOM tree (How to
+             * work with nodesets? how to select the right node from a nodeset?)
+             */
+            Element str = null;
+            if (input.isElement()) {
+                str = (Element) input.getSubNode();
+            } else {
+                throw (new CanonicalizationException(
+                        "Wrong input format - only element input supported"));
+            }
+
+            if (doDebug) {
+                log.debug("STR: " + str.toString());
+            }
+            /*
+             * The element to transform MUST be a SecurityTokenReference
+             * element.
+             */
+            SecurityTokenReference secRef = new SecurityTokenReference(str);
+            /*
+             * Third and forth step are performed by derefenceSTR()
+             */
+            Element dereferencedToken = dereferenceSTR(thisDoc, secRef);
+            /*
+             * C14n with specified algorithm. According to WSS Specification.
+             */
+            buf = canon.canonicalizeSubtree(dereferencedToken, "#default");
+            if (doDebug) {
+                bos = new ByteArrayOutputStream(buf.length);
+                bos.write(buf, 0, buf.length);
+                log.debug("after c14n: " + bos.toString());
+            }
+
+            /*
+             * Alert: Hacks ahead According to WSS spec an Apex node must
+             * contain a default namespace. If none is availabe in the first
+             * node of the c14n output (this is the apex element) then we do
+             * some editing to insert an empty default namespace
+             * 
+             * TODO: Rework theses hacks after c14n was updated and can be
+             * instructed to insert empty default namespace if required
+             */
+            // If the problem with c14n method is solved then just do:
+            // return new XMLSignatureInput(buf);
+            
+            // start of HACK
+            StringBuffer bf = new StringBuffer(new String(buf));
+            String bf1 = bf.toString();
+
+            /*
+             * Find start and end of first element <....>, this is the Apex node
+             */
+            int lt = bf1.indexOf("<");
+            int gt = bf1.indexOf(">");
+            /*
+             * Lookup the default namespace
+             */
+            int idx = bf1.indexOf(XMLNS);
+            /*
+             * If none found or if it is outside of this (Apex) element look for
+             * first blank in, insert default namespace there (this is the
+             * correct place according to c14n specification)
+             */
+            if (idx < 0 || idx > gt) {
+                idx = bf1.indexOf(" ");
+                bf.insert(idx + 1, "xmlns=\"\" ");
+                bf1 = bf.toString();
+            }
+            if (doDebug) {
+                log.debug("last result: ");
+                log.debug(bf1);
+            }
+            return new XMLSignatureInput(bf1.getBytes());
+        }
+        // End of HACK
+        catch (WSSecurityException ex) {
+            throw (new CanonicalizationException("WS Security Exception", ex));
+
+        }
+    }
+
+    private Element dereferenceSTR(Document doc, SecurityTokenReference secRef)
+            throws  WSSecurityException {
+
+        /*
+         * Third step: locate the security token referenced by the STR element.
+         * Either the Token is contained in the document as a
+         * BinarySecurityToken or stored in some key storage.
+         * 
+         * Forth step: after security token was located, prepare it. If its
+         * reference via a direct reference, i.e. a relative URI that references
+         * the BST directly in the message then just return that element.
+         * Otherwise wrap the located token in a newly created BST element as
+         * described in WSS Specification.
+         * 
+         */
+        Element tokElement = null;
+
+        /*
+         * First case: direct reference, according to chap 7.2 of OASIS WS
+         * specification (main document). Only in this case return a true
+         * reference to the BST. Copying is done by the caller.
+         */
+        if (secRef.containsReference()) {
+            if (doDebug) {
+                log.debug("STR: Reference");
+            }
+            tokElement = secRef.getTokenElement(doc, wsDocInfo);
+        }
+        /*
+         * second case: IssuerSerial, lookup in keystore, wrap in BST according
+         * to specification
+         */
+        else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
+            if (doDebug) {
+                log.debug("STR: IssuerSerial");
+            }
+            X509Certificate cert = null;
+            X509Certificate[] certs = secRef.getX509IssuerSerial(wsDocInfo
+                    .getCrypto());
+            if (certs == null || certs.length == 0 || certs[0] == null) {
+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+            }
+            cert = certs[0];
+            tokElement = createBSTX509(doc, cert, secRef.getElement());
+        }
+        /*
+         * third case: KeyIdentifier, must be SKI, lookup in keystore, wrap in
+         * BST according to specification. No other KeyIdentifier type handled
+         * here - just SKI
+         */
+        else if (secRef.containsKeyIdentifier()) {
+            if (doDebug) {
+                log.debug("STR: KeyIdentifier");
+            }
+            X509Certificate cert = null;
+            X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo
+                    .getCrypto());
+            if (certs == null || certs.length == 0 || certs[0] == null) {
+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+            }
+            cert = certs[0];
+            tokElement = createBSTX509(doc, cert, secRef.getElement());
+        }
+        return (Element) tokElement;
+    }
+
+    private Element createBSTX509(Document doc, X509Certificate cert,
+            Element secRefE) throws WSSecurityException {
+
+        byte data[];
+        try {
+            data = cert.getEncoded();
+        } catch (CertificateEncodingException e) {
+            throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+            "encodeError");
+        }
+        String prefix = WSSecurityUtil
+                .getPrefixNS(WSConstants.WSSE_NS, secRefE);
+        Element elem = doc.createElementNS(WSConstants.WSSE_NS, prefix
+                + ":BinarySecurityToken");
+        WSSecurityUtil.setNamespace(elem, WSConstants.WSSE_NS, prefix);
+        // elem.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "");
+        elem.setAttributeNS(null, "ValueType", X509Security.getType());
+        Text certText = doc.createTextNode(Base64.encode(data)); // no lne
+                                                                    // wrap
+        elem.appendChild(certText);
+        return elem;
+    }
+}
diff --git a/src/org/apache/ws/security/util/Base64.java b/src/org/apache/ws/security/util/Base64.java
new file mode 100644
index 0000000..43dfb83
--- /dev/null
+++ b/src/org/apache/ws/security/util/Base64.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright  1999-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import org.apache.ws.security.WSSecurityException;
+
+public class Base64 {
+    /**
+     * Implementation of MIME's Base64 encoding and decoding conversions.
+     * Optimized code. (raw version taken from oreilly.jonathan.util,
+     * and currently org.apache.xerces.ds.util.Base64)
+     *
+     * @author Raul Benito(Of the xerces copy, and little adaptations).
+     * @author Anli Shundi
+     * @author Christian Geuer-Pollmann
+     * @see <A HREF="ftp://ftp.isi.edu/in-notes/rfc2045.txt">RFC 2045</A>
+     * @see org.apache.xml.security.transforms.implementations.TransformBase64Decode
+     */
+
+    /**
+     * {@link org.apache.commons.logging} logging facility
+     */
+    static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
+            .getLog(Base64.class.getName());
+
+    /**
+     * Field BASE64DEFAULTLENGTH
+     */
+    public static final int BASE64DEFAULTLENGTH = 76;
+
+    /**
+     * Field _base64length
+     */
+    static int _base64length = Base64.BASE64DEFAULTLENGTH;
+
+    static private final int BASELENGTH = 255;
+
+    static private final int LOOKUPLENGTH = 64;
+
+    static private final int TWENTYFOURBITGROUP = 24;
+
+    static private final int EIGHTBIT = 8;
+
+    static private final int SIXTEENBIT = 16;
+
+    static private final int FOURBYTE = 4;
+
+    static private final int SIGN = -128;
+
+    static private final char PAD = '=';
+
+    static private final boolean fDebug = false;
+
+    static final private byte[] base64Alphabet = new byte[BASELENGTH];
+
+    static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+
+        for (int i = 0; i < BASELENGTH; i++) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++)
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+
+        for (int i = 26, j = 0; i <= 51; i++, j++)
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+
+        for (int i = 52, j = 0; i <= 61; i++, j++)
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        lookUpBase64Alphabet[62] = '+';
+        lookUpBase64Alphabet[63] = '/';
+
+    }
+
+    private Base64() {
+        // we don't allow instantiation
+    }
+
+    /**
+     * Encode a byte array and fold lines at the standard 76th character.
+     *
+     * @param binaryData <code>byte[]<code> to be base64 encoded
+     * @return the <code>String<code> with encoded data
+     */
+    public static String encode(byte[] binaryData) {
+        return encode(binaryData, BASE64DEFAULTLENGTH, false);
+    }
+
+    protected static boolean isWhiteSpace(byte octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    protected static boolean isPad(byte octect) {
+        return (octect == PAD);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    /**
+     * Encode a byte array in Base64 format and return an optionally
+     * wrapped line.
+     *
+     * @param binaryData <code>byte[]</code> data to be encoded
+     * @param length     <code>int<code> length of wrapped lines; No wrapping if less than 4.
+     * @return a <code>String</code> with encoded data
+     */
+    public static String encode(byte[] binaryData, int length, boolean wrap) {
+
+        if (length < 4) {
+            length = Integer.MAX_VALUE;
+        }
+
+        if (binaryData == null)
+            return null;
+
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
+                : numberTriplets;
+        int quartesPerLine = length / 4;
+        int numberLines = (numberQuartet - 1) / quartesPerLine;
+        char encodedData[];
+
+        encodedData = new char[(numberQuartet * 4) + (wrap ? numberLines : 0)];
+
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        int tripletsDone = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+
+        for (int line = 0; line < numberLines; line++) {
+            for (int quartet = 0; quartet < quartesPerLine; quartet++) {
+                b1 = binaryData[dataIndex++];
+                b2 = binaryData[dataIndex++];
+                b3 = binaryData[dataIndex++];
+
+                if (fDebug) {
+                    System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= "
+                            + b3);
+                }
+
+                l = (byte) (b2 & 0x0f);
+                k = (byte) (b1 & 0x03);
+
+                byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                        : (byte) ((b1) >> 2 ^ 0xc0);
+
+                byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                        : (byte) ((b2) >> 4 ^ 0xf0);
+                byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
+                        : (byte) ((b3) >> 6 ^ 0xfc);
+
+                if (fDebug) {
+                    System.out.println("val2 = " + val2);
+                    System.out.println("k4   = " + (k << 4));
+                    System.out.println("vak  = " + (val2 | (k << 4)));
+                }
+
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[val2
+                        | (k << 4)];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2)
+                        | val3];
+                encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+
+                tripletsDone++;
+            }
+            if (wrap) {
+                encodedData[encodedIndex++] = 0xa;
+            }
+        }
+
+        for (; tripletsDone < numberTriplets; tripletsDone++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
+                    : (byte) ((b3) >> 6 ^ 0xfc);
+
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded String containing Base64 data
+     * @return Array containing decoded data.
+     */
+    public static byte[] decode(String encoded) throws WSSecurityException {
+        byte[] base64Data = encoded.getBytes();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+
+        if (len % FOURBYTE != 0) {
+            throw new WSSecurityException("decoding.divisible.four");
+            //should be divisible by four
+        }
+
+        int numberQuadruple = (len / FOURBYTE);
+
+        if (numberQuadruple == 0)
+            return new byte[0];
+
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+
+        //decodedData      = new byte[ (numberQuadruple)*3];
+        dataIndex = (numberQuadruple - 1) * 4;
+        encodedIndex = (numberQuadruple - 1) * 3;
+        //first last bits.
+        b1 = base64Alphabet[base64Data[dataIndex++]];
+        b2 = base64Alphabet[base64Data[dataIndex++]];
+        if ((b1 == -1) || (b2 == -1)) {
+            throw new WSSecurityException("decoding.general");//if found "no data" just return null
+        }
+
+        byte d3, d4;
+        b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
+        b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
+        if ((b3 == -1) || (b4 == -1)) {
+            //Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) { //Two PAD e.g. 3c[Pad][Pad]
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                    throw new WSSecurityException("decoding.general");
+                decodedData = new byte[encodedIndex + 1];
+                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+            } else if (!isPad(d3) && isPad(d4)) { //One PAD  e.g. 3cQ[Pad]
+                if ((b3 & 0x3) != 0)//last 2 bits should be zero
+                    throw new WSSecurityException("decoding.general");
+                decodedData = new byte[encodedIndex + 2];
+                decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                decodedData[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            } else {
+                throw new WSSecurityException("decoding.general");//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
+            }
+        } else {
+            //No PAD e.g 3cQl
+            decodedData = new byte[encodedIndex + 3];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        encodedIndex = 0;
+        dataIndex = 0;
+        //the begin
+        for (i = numberQuadruple - 1; i > 0; i--) {
+            b1 = base64Alphabet[base64Data[dataIndex++]];
+            b2 = base64Alphabet[base64Data[dataIndex++]];
+            b3 = base64Alphabet[base64Data[dataIndex++]];
+            b4 = base64Alphabet[base64Data[dataIndex++]];
+
+            if ((b1 == -1) || (b2 == -1) || (b3 == -1) || (b4 == -1)) {
+                throw new WSSecurityException("decoding.general");//if found "no data" just return null
+            }
+
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data the byte array of base64 data (with WS)
+     * @return the new length
+     */
+    protected static int removeWhiteSpace(byte[] data) {
+        if (data == null)
+            return 0;
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            byte dataS = data[i];
+            if (!isWhiteSpace(dataS))
+                data[newSize++] = dataS;
+        }
+        return newSize;
+    }
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        // TODO Auto-generated method stub
+
+    }
+}
diff --git a/src/org/apache/ws/security/util/DOM2Writer.java b/src/org/apache/ws/security/util/DOM2Writer.java
new file mode 100644
index 0000000..33c40d3
--- /dev/null
+++ b/src/org/apache/ws/security/util/DOM2Writer.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import org.apache.ws.security.WSConstants;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+
+/**
+ * This class is a utility to serialize a DOM node as XML. This class
+ * uses the <code>DOM Level 2</code> APIs.
+ * The main difference between this class and DOMWriter is that this class
+ * generates and prints out namespace declarations.
+ *
+ * @author Matthew J. Duftler (duftler@us.ibm.com)
+ * @author Joseph Kesselman
+ */
+public class DOM2Writer {
+    public static final char NL = '\n';
+    public static final String LS = System.getProperty("line.separator",
+            (new Character(NL)).toString());
+
+    /**
+     * Return a string containing this node serialized as XML.
+     */
+    public static String nodeToString(Node node) {
+        StringWriter sw = new StringWriter();
+        serializeAsXML(node, sw, true);
+        return sw.toString();
+    }
+
+    /**
+     * Return a string containing this node serialized as XML.
+     */
+    public static String nodeToString(Node node, boolean omitXMLDecl) {
+        StringWriter sw = new StringWriter();
+        serializeAsXML(node, sw, omitXMLDecl);
+        return sw.toString();
+    }
+
+    /**
+     * Serialize this node into the writer as XML.
+     */
+    public static void serializeAsXML(Node node, Writer writer,
+                                      boolean omitXMLDecl) {
+        serializeAsXML(node, writer, omitXMLDecl, false);
+    }
+
+    /**
+     * Serialize this node into the writer as XML.
+     */
+    public static void serializeAsXML(Node node, Writer writer,
+                                      boolean omitXMLDecl,
+                                      boolean pretty) {
+        PrintWriter out = new PrintWriter(writer);
+        if (!omitXMLDecl) {
+            out.print("<?xml version=\"1.0\" encoding=UTF-8 ?>");
+        }
+        NSStack namespaceStack = new NSStack();
+        print(node, namespaceStack, out, pretty, 0);
+        out.flush();
+    }
+
+    private static void print(Node node, NSStack namespaceStack,
+                              PrintWriter out, boolean pretty,
+                              int indent) {
+        if (node == null) {
+            return;
+        }
+        boolean hasChildren = false;
+        int type = node.getNodeType();
+        switch (type) {
+            case Node.DOCUMENT_NODE:
+                {
+                    NodeList children = node.getChildNodes();
+                    if (children != null) {
+                        int numChildren = children.getLength();
+                        for (int i = 0; i < numChildren; i++) {
+                            print(children.item(i), namespaceStack, out,
+                                    pretty, indent);
+                        }
+                    }
+                    break;
+                }
+            case Node.ELEMENT_NODE:
+                {
+                    namespaceStack.push();
+                    if (pretty) {
+                        for (int i = 0; i < indent; i++)
+                            out.print(' ');
+                    }
+                    out.print('<' + node.getNodeName());
+                    String elPrefix = node.getPrefix();
+                    String elNamespaceURI = node.getNamespaceURI();
+                    if (elPrefix != null &&
+                            elNamespaceURI != null &&
+                            elPrefix.length() > 0) {
+                        boolean prefixIsDeclared = false;
+                        try {
+                            String namespaceURI = namespaceStack.getNamespaceURI(elPrefix);
+                            if (elNamespaceURI.equals(namespaceURI)) {
+                                prefixIsDeclared = true;
+                            }
+                        } catch (IllegalArgumentException e) {
+                        }
+                        if (!prefixIsDeclared) {
+                            printNamespaceDecl(node, namespaceStack, out);
+                        }
+                    }
+                    NamedNodeMap attrs = node.getAttributes();
+                    int len = (attrs != null) ? attrs.getLength() : 0;
+                    for (int i = 0; i < len; i++) {
+                        Attr attr = (Attr) attrs.item(i);
+                        out.print(' ' + attr.getNodeName() + "=\"");
+                        normalize(attr.getValue(), out);
+                        out.print('\"');
+                        String attrPrefix = attr.getPrefix();
+                        String attrNamespaceURI = attr.getNamespaceURI();
+                        if (attrPrefix != null && attrNamespaceURI != null) {
+                            boolean prefixIsDeclared = false;
+                            try {
+                                String namespaceURI = namespaceStack.getNamespaceURI(attrPrefix);
+                                if (attrNamespaceURI.equals(namespaceURI)) {
+                                    prefixIsDeclared = true;
+                                }
+                            } catch (IllegalArgumentException e) {
+                            }
+                            if (!prefixIsDeclared) {
+                                printNamespaceDecl(attr, namespaceStack, out);
+                            }
+                        }
+                    }
+                    NodeList children = node.getChildNodes();
+                    if (children != null) {
+                        int numChildren = children.getLength();
+                        hasChildren = (numChildren > 0);
+                        if (hasChildren) {
+                            out.print('>');
+                            if (pretty)
+                                out.print(LS);
+                        }
+                        for (int i = 0; i < numChildren; i++) {
+                            print(children.item(i), namespaceStack, out, pretty,
+                                    indent + 1);
+                        }
+                    } else {
+                        hasChildren = false;
+                    }
+                    if (!hasChildren) {
+                        out.print("/>");
+                        if (pretty)
+                            out.print(LS);
+                    }
+                    namespaceStack.pop();
+                    break;
+                }
+            case Node.ENTITY_REFERENCE_NODE:
+                {
+                    out.print('&');
+                    out.print(node.getNodeName());
+                    out.print(';');
+                    break;
+                }
+            case Node.CDATA_SECTION_NODE:
+                {
+                    out.print("<![CDATA[");
+                    out.print(node.getNodeValue());
+                    out.print("]]>");
+                    break;
+                }
+            case Node.TEXT_NODE:
+                {
+                    normalize(node.getNodeValue(), out);
+                    break;
+                }
+            case Node.COMMENT_NODE:
+                {
+                    out.print("<!--");
+                    out.print(node.getNodeValue());
+                    out.print("-->");
+                    if (pretty)
+                        out.print(LS);
+                    break;
+                }
+            case Node.PROCESSING_INSTRUCTION_NODE:
+                {
+                    out.print("<?");
+                    out.print(node.getNodeName());
+                    String data = node.getNodeValue();
+                    if (data != null && data.length() > 0) {
+                        out.print(' ');
+                        out.print(data);
+                    }
+                    out.println("?>");
+                    if (pretty)
+                        out.print(LS);
+                    break;
+                }
+        }
+        if (type == Node.ELEMENT_NODE && hasChildren == true) {
+            if (pretty) {
+                for (int i = 0; i < indent; i++)
+                    out.print(' ');
+            }
+            out.print("</");
+            out.print(node.getNodeName());
+            out.print('>');
+            if (pretty)
+                out.print(LS);
+            hasChildren = false;
+        }
+    }
+
+    private static void printNamespaceDecl(Node node,
+                                           NSStack namespaceStack,
+                                           PrintWriter out) {
+        switch (node.getNodeType()) {
+            case Node.ATTRIBUTE_NODE:
+                {
+                    printNamespaceDecl(((Attr) node).getOwnerElement(), node,
+                            namespaceStack, out);
+                    break;
+                }
+            case Node.ELEMENT_NODE:
+                {
+                    printNamespaceDecl((Element) node, node, namespaceStack, out);
+                    break;
+                }
+        }
+    }
+
+    private static void printNamespaceDecl(Element owner, Node node,
+                                           NSStack namespaceStack,
+                                           PrintWriter out) {
+        String namespaceURI = node.getNamespaceURI();
+        String prefix = node.getPrefix();
+        if (!(namespaceURI.equals(WSConstants.XMLNS_NS) && prefix.equals("xmlns")) &&
+                !(namespaceURI.equals(WSConstants.XML_NS) && prefix.equals("xml"))) {
+            if (WSSecurityUtil.getNamespace(prefix, owner) == null) {
+                out.print(" xmlns:" + prefix + "=\"" + namespaceURI + '\"');
+            }
+        } else {
+            prefix = node.getLocalName();
+            namespaceURI = node.getNodeValue();
+        }
+        namespaceStack.add(namespaceURI, prefix);
+    }
+
+    /**
+     * Normalizes and prints the given string.
+     */
+    public static void normalize(String s, PrintWriter fOut) {
+        int len = (s != null) ? s.length() : 0;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '<':
+                    {
+                        fOut.print("&lt;");
+                        break;
+                    }
+                case '>':
+                    {
+                        fOut.print("&gt;");
+                        break;
+                    }
+                case '&':
+                    {
+                        fOut.print("&amp;");
+                        break;
+                    }
+                case '"':
+                    {
+                        fOut.print("&quot;");
+                        break;
+                    }
+                case '\r':
+                case '\n':
+                default:
+                    {
+                        fOut.print(c);
+                    }
+            }
+        }
+    }
+}
diff --git a/src/org/apache/ws/security/util/Loader.java b/src/org/apache/ws/security/util/Loader.java
new file mode 100644
index 0000000..ca7198e
--- /dev/null
+++ b/src/org/apache/ws/security/util/Loader.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+
+/**
+ * Load resources (or images) from various sources.
+ * <p/>
+ *
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class Loader {
+    private static Log log = LogFactory.getLog(Loader.class.getName());
+
+    /**
+     * This method will search for <code>resource</code> in different
+     * places. The rearch order is as follows:
+     * <ol>
+     * <p><li>Search for <code>resource</code> using the thread context
+     * class loader under Java2. If that fails, search for
+     * <code>resource</code> using the class loader that loaded this
+     * class (<code>Loader</code>).
+     * <p><li>Try one last time with
+     * <code>ClassLoader.getSystemResource(resource)</code>, that is is
+     * using the system class loader in JDK 1.2 and virtual machine's
+     * built-in class loader in JDK 1.1.
+     * </ol>
+     * <p/>
+     *
+     * @param resource
+     * @return TODO
+     */
+    static public URL getResource(String resource) {
+        ClassLoader classLoader = null;
+        URL url = null;
+        try {
+            // We could not find resource. Ler us now try with the
+            // classloader that loaded this class.
+            classLoader = getTCL();
+            if (classLoader != null) {
+                log.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
+                url = classLoader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+        } catch (Throwable t) {
+            log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
+        }
+    
+        // Last ditch attempt: get the resource from the class path. It
+        // may be the case that clazz was loaded by the Extentsion class
+        // loader which the parent of the system class loader. Hence the
+        // code below.
+        log.debug("Trying to find [" + resource + "] using ClassLoader.getSystemResource().");
+        return ClassLoader.getSystemResource(resource);
+    }
+    
+
+    /**
+     * Try to get the resource with the specified class loader
+     * <p/>
+     *
+     * @param cl
+     * @param clazz
+     * @return Class
+     * @throws ClassNotFoundException
+     */
+    static public URL getResource(ClassLoader loader, String resource) throws ClassNotFoundException {
+        URL url = null;
+        try {
+            if (loader != null) {
+                log.debug("Trying to find [" + resource + "] using " + loader + " class loader.");
+                url = loader.getResource(resource);
+                if (url != null) {
+                    return url;
+                }
+            }
+        } catch (Throwable t) {
+            log.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
+        }
+        return getResource(resource);
+    }
+
+    /**
+     * Get the Thread context class loader.
+     * <p/>
+     *
+     * @return
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     */
+    static public ClassLoader getTCL() throws IllegalAccessException, InvocationTargetException {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+    /**
+     * Try the specified classloader and then fall back to the loadClass
+     * <p/>
+     *
+     * @param cl
+     * @param clazz
+     * @return Class
+     * @throws ClassNotFoundException
+     */
+    static public Class loadClass(ClassLoader loader, String clazz) throws ClassNotFoundException {
+        try {
+            if(loader != null) {
+                Class c = loader.loadClass(clazz);
+                if (c != null)
+                    return c;
+            }
+        } catch (Throwable e) {
+        }
+        return loadClass(clazz);
+    }
+
+    /**
+     * If running under JDK 1.2 load the specified class using the
+     * <code>Thread</code> <code>contextClassLoader</code> if that
+     * fails try Class.forname.
+     * <p/>
+     *
+     * @param clazz
+     * @return TODO
+     * @throws ClassNotFoundException
+     */
+    static public Class loadClass(String clazz) throws ClassNotFoundException {
+        try {
+            ClassLoader tcl = getTCL();	
+            
+            if(tcl != null) {
+                Class c = tcl.loadClass(clazz);
+                if (c != null)
+                    return c;
+            }
+        } catch (Throwable e) {
+        }
+        // we reached here because tcl was null or because of a
+        // security exception, or because clazz could not be loaded...
+        // In any case we now try one more time
+        return Class.forName(clazz);
+    }
+}
diff --git a/src/org/apache/ws/security/util/Mapping.java b/src/org/apache/ws/security/util/Mapping.java
new file mode 100644
index 0000000..59bc5d9
--- /dev/null
+++ b/src/org/apache/ws/security/util/Mapping.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import java.io.Serializable;
+
+public class Mapping implements Serializable {
+    private String namespaceURI;
+    private int namespaceHash;
+
+    private String prefix;
+    private int prefixHash;
+
+    public Mapping(String namespaceURI, String prefix) {
+        setPrefix(prefix);
+        setNamespaceURI(namespaceURI);
+    }
+
+    public String getNamespaceURI() {
+        return namespaceURI;
+    }
+
+    public int getNamespaceHash() {
+        return namespaceHash;
+    }
+
+    public void setNamespaceURI(String namespaceURI) {
+        this.namespaceURI = namespaceURI;
+        this.namespaceHash = namespaceURI.hashCode();
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public int getPrefixHash() {
+        return prefixHash;
+    }
+
+    public void setPrefix(String prefix) {
+        this.prefix = prefix;
+        this.prefixHash = prefix.hashCode();
+    }
+
+}
diff --git a/src/org/apache/ws/security/util/NSStack.java b/src/org/apache/ws/security/util/NSStack.java
new file mode 100644
index 0000000..898fe93
--- /dev/null
+++ b/src/org/apache/ws/security/util/NSStack.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.ArrayList;
+
+/**
+ * The abstraction this class provides is a push down stack of variable
+ * length frames of prefix to namespace mappings.  Used for keeping track
+ * of what namespaces are active at any given point as an XML document is
+ * traversed or produced.
+ * <p/>
+ * From a performance point of view, this data will both be modified frequently
+ * (at a minimum, there will be one push and pop per XML element processed),
+ * and scanned frequently (many of the "good" mappings will be at the bottom
+ * of the stack).  The one saving grace is that the expected maximum
+ * cardinalities of the number of frames and the number of total mappings
+ * is only in the dozens, representing the nesting depth of an XML document
+ * and the number of active namespaces at any point in the processing.
+ * <p/>
+ * Accordingly, this stack is implemented as a single array, will null
+ * values used to indicate frame boundaries.
+ *
+ * @author James Snell
+ * @author Glen Daniels (gdaniels@apache.org)
+ * @author Sam Ruby (rubys@us.ibm.com)
+ */
+public class NSStack {
+    protected static Log log =
+            LogFactory.getLog(NSStack.class.getName());
+
+    private Mapping[] stack;
+    private int top = 0;
+    private int iterator = 0;
+    private int currentDefaultNS = -1;
+    // invariant member variable to track low-level logging requirements
+    // we cache this once per instance lifecycle to avoid repeated lookups
+    // in heavily used code.
+    private final boolean traceEnabled = log.isTraceEnabled();
+
+    public NSStack() {
+        stack = new Mapping[32];
+        stack[0] = null;
+    }
+
+    /**
+     * Create a new frame at the top of the stack.
+     */
+    public void push() {
+        top++;
+        if (top >= stack.length) {
+            Mapping newstack[] = new Mapping[stack.length * 2];
+            System.arraycopy(stack, 0, newstack, 0, stack.length);
+            stack = newstack;
+        }
+        if (traceEnabled)
+            log.trace("NSPush (" + stack.length + ")");
+        stack[top] = null;
+    }
+
+    /**
+     * Remove the top frame from the stack.
+     */
+    public void pop() {
+        clearFrame();
+        top--;
+
+        // If we've moved below the current default NS, figure out the new
+        // default (if any)
+        if (top < currentDefaultNS) {
+            // Reset the currentDefaultNS to ignore the frame just removed.
+            currentDefaultNS = top;
+            while (currentDefaultNS > 0) {
+                if (stack[currentDefaultNS] != null &&
+                        stack[currentDefaultNS].getPrefix().length() == 0)
+                    break;
+                currentDefaultNS--;
+            }
+        }
+        if (top == 0) {
+            if (traceEnabled)
+                log.trace("NSPop (empty)");
+            return;
+        }
+        if (traceEnabled) {
+            log.trace("NSPop (" + stack.length + ")");
+        }
+    }
+
+    /**
+     * Return a copy of the current frame.  Returns null if none are present.
+     */
+    public ArrayList cloneFrame() {
+        if (stack[top] == null) return null;
+        ArrayList clone = new ArrayList();
+        for (Mapping map = topOfFrame(); map != null; map = next()) {
+            clone.add(map);
+        }
+        return clone;
+    }
+
+    /**
+     * Remove all mappings from the current frame.
+     */
+    private void clearFrame() {
+        while (stack[top] != null) top--;
+    }
+
+    /**
+     * Reset the embedded iterator in this class to the top of the current
+     * (i.e., last) frame.  Note that this is not threadsafe, nor does it
+     * provide multiple iterators, so don't use this recursively.  Nor
+     * should you modify the stack while iterating over it.
+     */
+    public Mapping topOfFrame() {
+        iterator = top;
+        while (stack[iterator] != null) iterator--;
+        iterator++;
+        return next();
+    }
+
+    /**
+     * Return the next namespace mapping in the top frame.
+     */
+    public Mapping next() {
+        if (iterator > top) {
+            return null;
+        } else {
+            return stack[iterator++];
+        }
+    }
+
+    /**
+     * Add a mapping for a namespaceURI to the specified prefix to the top
+     * frame in the stack.  If the prefix is already mapped in that frame,
+     * remap it to the (possibly different) namespaceURI.
+     */
+    public void add(String namespaceURI, String prefix) {
+        int idx = top;
+        try {
+            // Replace duplicate prefixes (last wins - this could also fault)
+            for (int cursor = top; stack[cursor] != null; cursor--) {
+                if (stack[cursor].getPrefix().equals(prefix)) {
+                    stack[cursor].setNamespaceURI(namespaceURI);
+                    idx = cursor;
+                    return;
+                }
+            }
+            push();
+            stack[top] = new Mapping(namespaceURI, prefix);
+            idx = top;
+        } finally {
+            // If this is the default namespace, note the new in-scope
+            // default is here.
+            if (prefix.length() == 0) {
+                currentDefaultNS = idx;
+            }
+        }
+    }
+
+    /**
+     * Return an active prefix for the given namespaceURI.  NOTE : This
+     * may return null even if the namespaceURI was actually mapped further
+     * up the stack IF the prefix which was used has been repeated further
+     * down the stack.  I.e.:
+     * <p/>
+     * <pre:outer xmlns:pre="namespace">
+     * <pre:inner xmlns:pre="otherNamespace">
+     * *here's where we're looking*
+     * </pre:inner>
+     * </pre:outer>
+     * <p/>
+     * If we look for a prefix for "namespace" at the indicated spot, we won't
+     * find one because "pre" is actually mapped to "otherNamespace"
+     */
+    public String getPrefix(String namespaceURI, boolean noDefault) {
+        if ((namespaceURI == null) || (namespaceURI.equals("")))
+            return null;
+        int hash = namespaceURI.hashCode();
+
+        // If defaults are OK, and the given NS is the current default,
+        // return "" as the prefix to favor defaults where possible.
+        if (!noDefault && currentDefaultNS > 0 && stack[currentDefaultNS] != null &&
+                namespaceURI.equals(stack[currentDefaultNS].getNamespaceURI()))
+            return "";
+        for (int cursor = top; cursor > 0; cursor--) {
+            Mapping map = stack[cursor];
+            if (map == null) continue;
+            if (map.getNamespaceHash() == hash &&
+                    map.getNamespaceURI().equals(namespaceURI)) {
+                String possiblePrefix = map.getPrefix();
+                if (noDefault && possiblePrefix.length() == 0) continue;
+
+                // now make sure that this is the first occurance of this 
+                // particular prefix
+                int ppHash = possiblePrefix.hashCode();
+                for (int cursor2 = top; true; cursor2--) {
+                    if (cursor2 == cursor) return possiblePrefix;
+                    map = stack[cursor2];
+                    if (map == null) continue;
+                    if (ppHash == map.getPrefixHash() &&
+                            possiblePrefix.equals(map.getPrefix()))
+                        break;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return an active prefix for the given namespaceURI, including
+     * the default prefix ("").
+     */
+    public String getPrefix(String namespaceURI) {
+        return getPrefix(namespaceURI, false);
+    }
+
+    /**
+     * Given a prefix, return the associated namespace (if any).
+     */
+    public String getNamespaceURI(String prefix) {
+        if (prefix == null)
+            prefix = "";
+        int hash = prefix.hashCode();
+        for (int cursor = top; cursor > 0; cursor--) {
+            Mapping map = stack[cursor];
+            if (map == null) continue;
+            if (map.getPrefixHash() == hash && map.getPrefix().equals(prefix))
+                return map.getNamespaceURI();
+        }
+        return null;
+    }
+
+    /**
+     * Produce a trace dump of the entire stack, starting from the top and
+     * including frame markers.
+     */
+    public void dump(String dumpPrefix) {
+        for (int cursor = top; cursor > 0; cursor--) {
+            Mapping map = stack[cursor];
+            if (map == null) {
+                log.trace(dumpPrefix + "stackFrame00");
+            } else {
+                log.trace(dumpPrefix + map.getNamespaceURI() + " -> " + map.getPrefix());
+            }
+        }
+    }
+}
diff --git a/src/org/apache/ws/security/util/StringUtil.java b/src/org/apache/ws/security/util/StringUtil.java
new file mode 100644
index 0000000..c64607b
--- /dev/null
+++ b/src/org/apache/ws/security/util/StringUtil.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ * 
+ * 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.apache.ws.security.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StringUtil {
+    /**
+     * An empty immutable <code>String</code> array.
+     */
+    public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    /**
+     * Tests if this string starts with the specified prefix (Ignoring whitespaces)
+     *
+     * @param prefix
+     * @param string
+     * @return boolean
+     */
+    public static boolean startsWithIgnoreWhitespaces(String prefix, String string) {
+        int index1 = 0;
+        int index2 = 0;
+        int length1 = prefix.length();
+        int length2 = string.length();
+        char ch1 = ' ';
+        char ch2 = ' ';
+        while (index1 < length1 && index2 < length2) {
+            while (index1 < length1 && Character.isWhitespace(ch1 = prefix.charAt(index1))) {
+                index1++;
+            }
+            while (index2 < length2 && Character.isWhitespace(ch2 = string.charAt(index2))) {
+                index2++;
+            }
+            if (index1 == length1 && index2 == length2) {
+                return true;
+            }
+            if (ch1 != ch2) {
+                return false;
+            }
+            index1++;
+            index2++;
+        }
+        if (index1 < length1 && index2 >= length2)
+            return false;
+        return true;
+    }
+
+    /**
+     * <p>Splits the provided text into an array, separator specified.
+     * This is an alternative to using StringTokenizer.</p>
+     * <p/>
+     * <p>The separator is not included in the returned String array.
+     * Adjacent separators are treated as one separator.</p>
+     * <p/>
+     * <p>A <code>null</code> input String returns <code>null</code>.</p>
+     * <p/>
+     * <pre>
+     * StringUtils.split(null, *)         = null
+     * StringUtils.split("", *)           = []
+     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
+     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
+     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
+     * StringUtils.split("a\tb\nc", null) = ["a", "b", "c"]
+     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
+     * </pre>
+     *
+     * @param str           the String to parse, may be null
+     * @param separatorChar the character used as the delimiter,
+     *                      <code>null</code> splits on whitespace
+     * @return an array of parsed Strings, <code>null</code> if null String input
+     */
+    public static String[] split(String str, char separatorChar) {
+        if (str == null) {
+            return null;
+        }
+        int len = str.length();
+        if (len == 0) {
+            return EMPTY_STRING_ARRAY;
+        }
+        List list = new ArrayList();
+        int i = 0, start = 0;
+        boolean match = false;
+        while (i < len) {
+            if (str.charAt(i) == separatorChar) {
+                if (match) {
+                    list.add(str.substring(start, i));
+                    match = false;
+                }
+                start = ++i;
+                continue;
+            }
+            match = true;
+            i++;
+        }
+        if (match) {
+            list.add(str.substring(start, i));
+        }
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+}
diff --git a/src/org/apache/ws/security/util/UUIDGenerator.java b/src/org/apache/ws/security/util/UUIDGenerator.java
new file mode 100644
index 0000000..efc3526
--- /dev/null
+++ b/src/org/apache/ws/security/util/UUIDGenerator.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.apache.ws.security.util;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+import java.util.Random;
+
+/**
+ * UUID generator (taken from Axis2) 
+ */
+public class UUIDGenerator {
+
+    private static String baseUUID = null;
+    private static long incrementingValue = 0;
+
+
+    private static Random myRand = null;
+
+    /**
+     * MD5 a random string with localhost/date etc will return 128 bits
+     * construct a string of 18 characters from those bits.
+     *
+     * @return string
+     */
+    public static String getUUID() {
+        if (baseUUID == null) {
+            baseUUID = getInitialUUID();
+        }
+        if(++incrementingValue >= Long.MAX_VALUE){
+            incrementingValue = 0;
+        }
+        return "urn:uuid:" + baseUUID + new Date().getTime() + incrementingValue;
+    }
+
+    protected static String getInitialUUID() {
+        if (myRand == null) {
+            myRand = new Random();
+        }
+        long rand = myRand.nextLong();
+        String sid;
+        try {
+            sid = InetAddress.getLocalHost().toString();
+        } catch (UnknownHostException e) {
+            sid = Thread.currentThread().getName();
+        }
+        StringBuffer sb = new StringBuffer();
+        sb.append(sid);
+        sb.append(":");
+        sb.append(Long.toString(rand));
+        MessageDigest md5 = null;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            //System.out.println("Error: " + e);
+            //todo heve to be properly handle
+        }
+        md5.update(sb.toString().getBytes());
+        byte[] array = md5.digest();
+        StringBuffer sb2 = new StringBuffer();
+        for (int j = 0; j < array.length; ++j) {
+            int b = array[j] & 0xFF;
+            sb2.append(Integer.toHexString(b));
+        }
+        int begin = myRand.nextInt();
+        if (begin < 0) begin = begin * -1;
+        begin = begin % 8;
+        return sb2.toString().substring(begin, begin + 18).toUpperCase();
+    }
+
+}
diff --git a/src/org/apache/ws/security/util/WSSecurityUtil.java b/src/org/apache/ws/security/util/WSSecurityUtil.java
new file mode 100644
index 0000000..4a0105c
--- /dev/null
+++ b/src/org/apache/ws/security/util/WSSecurityUtil.java
@@ -0,0 +1,972 @@
+/*
+ * Copyright  2003-2006 The Apache Software Foundation, or their licensors, as
+ * appropriate.
+ *
+ *  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.apache.ws.security.util;
+
+import java.util.Set;
+import org.apache.ws.security.handler.WSHandlerResult;
+import java.util.Iterator;
+import java.security.cert.X509Certificate;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAP11Constants;
+import org.apache.ws.security.SOAP12Constants;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.ws.security.util.Base64;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.namespace.QName;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.util.Vector;
+
+/**
+ * WS-Security Utility methods. <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com).
+ */
+public class WSSecurityUtil {
+    private static Log log = LogFactory.getLog(WSSecurityUtil.class);
+
+    private static boolean doDebug = false;
+
+    static {
+        doDebug = log.isDebugEnabled();
+    }
+
+    /**
+     * Returns the first WS-Security header element for a given actor. Only one
+     * WS-Security header is allowed for an actor.
+     * 
+     * @param doc
+     * @param actor
+     * @return the <code>wsse:Security</code> element or <code>null</code>
+     *         if not such element found
+     */
+    public static Element getSecurityHeader(Document doc, String actor,
+            SOAPConstants sc) {
+        Element soapHeaderElement = (Element) getDirectChild(doc
+                .getFirstChild(), sc.getHeaderQName().getLocalPart(), sc
+                .getEnvelopeURI());
+
+        if (soapHeaderElement == null) { // no SOAP header at all
+            return null;
+        }
+
+        // get all wsse:Security nodes
+        NodeList list = null;
+        int len = 0;
+        list = soapHeaderElement.getElementsByTagNameNS(WSConstants.WSSE_NS,
+                WSConstants.WSSE_LN);
+        if (list == null) {
+            return null;
+        } else {
+            len = list.getLength();
+        }
+        Element elem;
+        Attr attr;
+        String hActor;
+        for (int i = 0; i < len; i++) {
+            elem = (Element) list.item(i);
+            attr = elem.getAttributeNodeNS(sc.getEnvelopeURI(), sc
+                    .getRoleAttributeQName().getLocalPart());
+            hActor = (attr != null) ? attr.getValue() : null;
+            if (WSSecurityUtil.isActorEqual(actor, hActor)) {
+                return elem;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Compares two actor strings and returns true if these are equal. Takes
+     * care of the null length strings and uses ignore case.
+     * 
+     * @param actor
+     * @param hActor
+     * @return TODO
+     */
+    public static boolean isActorEqual(String actor, String hActor) {
+        if ((((hActor == null) || (hActor.length() == 0)) && ((actor == null) || (actor
+                .length() == 0)))
+                || ((hActor != null) && (actor != null) && hActor
+                        .equalsIgnoreCase(actor))) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Gets a direct child with specified localname and namespace. <p/>
+     * 
+     * @param fNode
+     *            the node where to start the search
+     * @param localName
+     *            local name of the child to get
+     * @param namespace
+     *            the namespace of the child to get
+     * @return the node or <code>null</code> if not such node found
+     */
+    public static Node getDirectChild(Node fNode, String localName,
+            String namespace) {
+        for (Node currentChild = fNode.getFirstChild(); currentChild != null; currentChild = currentChild
+                .getNextSibling()) {
+            if (localName.equals(currentChild.getLocalName())
+                    && namespace.equals(currentChild.getNamespaceURI())) {
+                return currentChild;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * return the first soap "Body" element. <p/>
+     * 
+     * @param doc
+     * @return the body element or <code>null</code> if document does not
+     *         contain a SOAP body
+     */
+    public static Element findBodyElement(Document doc, SOAPConstants sc) {
+        Element soapBodyElement = (Element) WSSecurityUtil.getDirectChild(doc
+                .getFirstChild(), sc.getBodyQName().getLocalPart(), sc
+                .getEnvelopeURI());
+        return soapBodyElement;
+    }
+
+    /**
+     * Returns the first element that matches <code>name</code> and
+     * <code>namespace</code>. <p/> This is a replacement for a XPath lookup
+     * <code>//name</code> with the given namespace. It's somewhat faster than
+     * XPath, and we do not deal with prefixes, just with the real namespace URI
+     * 
+     * @param startNode
+     *            Where to start the search
+     * @param name
+     *            Local name of the element
+     * @param namespace
+     *            Namespace URI of the element
+     * @return The found element or <code>null</code>
+     */
+    public static Node findElement(Node startNode, String name, String namespace) {
+
+        /*
+         * Replace the formely recursive implementation with a depth-first-loop
+         * lookup
+         */
+        if (startNode == null) {
+            return null;
+        }
+        Node startParent = startNode.getParentNode();
+        Node processedNode = null;
+
+        while (startNode != null) {
+            // start node processing at this point
+            if (startNode.getNodeType() == Node.ELEMENT_NODE
+                    && startNode.getLocalName().equals(name)) {
+                String ns = startNode.getNamespaceURI();
+                if (ns != null && ns.equals(namespace)) {
+                    return startNode;
+                }
+
+                if ((namespace == null || namespace.length() == 0)
+                        && (ns == null || ns.length() == 0)) {
+                    return startNode;
+                }
+            }
+            processedNode = startNode;
+            startNode = startNode.getFirstChild();
+
+            // no child, this node is done.
+            if (startNode == null) {
+                // close node processing, get sibling
+                startNode = processedNode.getNextSibling();
+            }
+            // no more siblings, get parent, all children
+            // of parent are processed.
+            while (startNode == null) {
+                processedNode = processedNode.getParentNode();
+                if (processedNode == startParent) {
+                    return null;
+                }
+                // close parent node processing (processed node now)
+                startNode = processedNode.getNextSibling();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the single element that containes an Id with value
+     * <code>uri</code> and <code>namespace</code>. <p/> This is a
+     * replacement for a XPath Id lookup with the given namespace. It's somewhat
+     * faster than XPath, and we do not deal with prefixes, just with the real
+     * namespace URI
+     * 
+     * If there are multiple elements, we log a warning and return null as this
+     * can be used to get around the signature checking.
+     * 
+     * @param startNode
+     *            Where to start the search
+     * @param value
+     *            Value of the Id attribute
+     * @param namespace
+     *            Namespace URI of the Id
+     * @return The found element if there was exactly one match, or
+     *         <code>null</code> otherwise
+     */
+    public static Element findElementById(Node startNode, String value,
+            String namespace) {
+        Element foundElement = null;
+
+        /*
+         * Replace the formely recursive implementation with a depth-first-loop
+         * lookup
+         */
+        if (startNode == null) {
+            return null;
+        }
+        Node startParent = startNode.getParentNode();
+        Node processedNode = null;
+
+        while (startNode != null) {
+            // start node processing at this point
+            if (startNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element se = (Element) startNode;
+                if (se.hasAttributeNS(namespace, "Id")
+                        && value.equals(se.getAttributeNS(namespace, "Id"))) {
+                    if (foundElement == null) {
+                        foundElement = se; // Continue searching to find
+                        // duplicates
+                    } else {
+                        log
+                                .warn("Multiple elements with the same 'Id' attribute value!");
+                        return null;
+                    }
+                }
+            }
+
+            processedNode = startNode;
+            startNode = startNode.getFirstChild();
+
+            // no child, this node is done.
+            if (startNode == null) {
+                // close node processing, get sibling
+                startNode = processedNode.getNextSibling();
+            }
+            // no more siblings, get parent, all children
+            // of parent are processed.
+            while (startNode == null) {
+                processedNode = processedNode.getParentNode();
+                if (processedNode == startParent) {
+                    return foundElement;
+                }
+                // close parent node processing (processed node now)
+                startNode = processedNode.getNextSibling();
+            }
+        }
+        return foundElement;
+    }
+
+    /**
+     * set the namespace if it is not set already. <p/>
+     * 
+     * @param element
+     * @param namespace
+     * @param prefix
+     * @return TODO
+     */
+    public static String setNamespace(Element element, String namespace,
+            String prefix) {
+        String pre = getPrefixNS(namespace, element);
+        if (pre != null) {
+            return pre;
+        }
+        element.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + prefix,
+                namespace);
+        return prefix;
+    }
+
+    /*
+     * ** The following methods were copied over from aixs.utils.XMLUtils and
+     * adapted
+     */
+
+    public static String getPrefixNS(String uri, Node e) {
+        while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) {
+            NamedNodeMap attrs = e.getAttributes();
+            for (int n = 0; n < attrs.getLength(); n++) {
+                Attr a = (Attr) attrs.item(n);
+                String name;
+                if ((name = a.getName()).startsWith("xmlns:")
+                        && a.getNodeValue().equals(uri)) {
+                    return name.substring(6);
+                }
+            }
+            e = e.getParentNode();
+        }
+        return null;
+    }
+
+    public static String getNamespace(String prefix, Node e) {
+        while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) {
+            Attr attr = null;
+            if (prefix == null) {
+                attr = ((Element) e).getAttributeNode("xmlns");
+            } else {
+                attr = ((Element) e).getAttributeNodeNS(WSConstants.XMLNS_NS,
+                        prefix);
+            }
+            if (attr != null)
+                return attr.getValue();
+            e = e.getParentNode();
+        }
+        return null;
+    }
+
+    /**
+     * Return a QName when passed a string like "foo:bar" by mapping the "foo"
+     * prefix to a namespace in the context of the given Node.
+     * 
+     * @return a QName generated from the given string representation
+     */
+    public static QName getQNameFromString(String str, Node e) {
+        return getQNameFromString(str, e, false);
+    }
+
+    /**
+     * Return a QName when passed a string like "foo:bar" by mapping the "foo"
+     * prefix to a namespace in the context of the given Node. If default
+     * namespace is found it is returned as part of the QName.
+     * 
+     * @return a QName generated from the given string representation
+     */
+    public static QName getFullQNameFromString(String str, Node e) {
+        return getQNameFromString(str, e, true);
+    }
+
+    private static QName getQNameFromString(String str, Node e,
+            boolean defaultNS) {
+        if (str == null || e == null)
+            return null;
+        int idx = str.indexOf(':');
+        if (idx > -1) {
+            String prefix = str.substring(0, idx);
+            String ns = getNamespace(prefix, e);
+            if (ns == null)
+                return null;
+            return new QName(ns, str.substring(idx + 1));
+        } else {
+            if (defaultNS) {
+                String ns = getNamespace(null, e);
+                if (ns != null)
+                    return new QName(ns, str);
+            }
+            return new QName("", str);
+        }
+    }
+
+    /**
+     * Return a string for a particular QName, mapping a new prefix if
+     * necessary.
+     */
+    public static String getStringForQName(QName qname, Element e) {
+        String uri = qname.getNamespaceURI();
+        String prefix = getPrefixNS(uri, e);
+        if (prefix == null) {
+            int i = 1;
+            prefix = "ns" + i;
+            while (getNamespace(prefix, e) != null) {
+                i++;
+                prefix = "ns" + i;
+            }
+            e.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + prefix, uri);
+        }
+        return prefix + ":" + qname.getLocalPart();
+    }
+
+    /* ** up to here */
+
+    /**
+     * Search for an element given its wsu:id. <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param id
+     *            the Id of the element
+     * @return the found element or null if no element with the Id exists
+     */
+    public static Element getElementByWsuId(Document doc, String id) {
+
+        if (id == null) {
+            return null;
+        }
+        id = getIDfromReference(id);
+        return WSSecurityUtil.findElementById(doc.getDocumentElement(), id,
+                WSConstants.WSU_NS);
+    }
+
+    /**
+     * Turn a reference (eg "#5") into an ID (eg "5").
+     * 
+     * @param ref
+     * @return ref trimmed and with the leading "#" removed, or null if not
+     *         correctly formed
+     */
+    public static String getIDfromReference(String ref) {
+        String id = ref.trim();
+        if ((id.length() == 0) || (id.charAt(0) != '#')) {
+            return null;
+        }
+        return id.substring(1);
+    }
+
+    /**
+     * Search for an element given its generic id. <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param id
+     *            the Id of the element
+     * @return the found element or null if no element with the Id exists
+     */
+    public static Element getElementByGenId(Document doc, String id) {
+        if (id == null) {
+            return null;
+        }
+        id = id.trim();
+        if ((id.length() == 0) || (id.charAt(0) != '#')) {
+            return null;
+        }
+        id = id.substring(1);
+        return WSSecurityUtil.findElementById(doc.getDocumentElement(), id,
+                null);
+    }
+
+    /**
+     * Create a BinarySecurityToken element <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param wsuIdVal
+     *            the value for the wsu:Id
+     * @return then BST element (DOM element)
+     */
+    public static Element createBinarySecurityToken(Document doc,
+            String wsuIdVal) {
+        Element retVal = doc.createElementNS(WSConstants.WSSE_NS,
+                "wsse:BinarySecurityToken");
+        retVal.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsu",
+                WSConstants.WSU_NS);
+        retVal.setAttributeNS(WSConstants.WSU_NS, "wsu:Id", wsuIdVal);
+        retVal.setAttributeNS(null, "ValueType", X509Security.getType());
+        retVal.setAttributeNS(null, "EncodingType",
+                BinarySecurity.BASE64_ENCODING);
+        return retVal;
+    }
+
+    /**
+     * create a new element in the same namespace <p/>
+     * 
+     * @param parent
+     *            for the new element
+     * @param localName
+     *            of the new element
+     * @return the new element
+     */
+    private static Element createElementInSameNamespace(Element parent,
+            String localName) {
+        String prefix = parent.getPrefix();
+        if (prefix == null) {
+            prefix = "";
+        }
+        String qName = prefix + ":" + localName;
+        String nsUri = parent.getNamespaceURI();
+        return parent.getOwnerDocument().createElementNS(nsUri, qName);
+    }
+
+    /**
+     * find a child element with given namespace and local name <p/>
+     * 
+     * @param parent
+     *            the node to start the search
+     * @param namespaceUri
+     *            of the element
+     * @param localName
+     *            of the eleme
+     * @return the found element or null if the element does not exist
+     */
+    private static Element findChildElement(Element parent,
+            String namespaceUri, String localName) {
+        NodeList children = parent.getChildNodes();
+        int len = children.getLength();
+        for (int i = 0; i < len; i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                Element elementChild = (Element) child;
+                if (namespaceUri.equals(elementChild.getNamespaceURI())
+                        && localName.equals(elementChild.getLocalName())) {
+                    return elementChild;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * append a child element <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param parent
+     *            element of this child element
+     * @param child
+     *            the element to append
+     * @return the child element
+     */
+    public static Element appendChildElement(Document doc, Element parent,
+            Element child) {
+        Node whitespaceText = doc.createTextNode("\n");
+        parent.appendChild(whitespaceText);
+        parent.appendChild(child);
+        return child;
+    }
+
+    /**
+     * prepend a child element <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param parent
+     *            element of this child element
+     * @param child
+     *            the element to append
+     * @param addWhitespace
+     *            if true prepend a newline before child
+     * @return the child element
+     */
+    public static Element prependChildElement(Document doc, Element parent,
+            Element child, boolean addWhitespace) {
+        Node firstChild = parent.getFirstChild();
+        if (firstChild == null) {
+            parent.appendChild(child);
+        } else {
+            parent.insertBefore(child, firstChild);
+        }
+        if (addWhitespace) {
+            Node whitespaceText = doc.createTextNode("\n");
+            parent.insertBefore(whitespaceText, child);
+        }
+        return child;
+    }
+
+    /**
+     * find the first ws-security header block <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param envelope
+     *            the SOAP envelope
+     * @param doCreate
+     *            if true create a new WSS header block if none exists
+     * @return the WSS header or null if none found and doCreate is false
+     */
+    public static Element findWsseSecurityHeaderBlock(Document doc,
+            Element envelope, boolean doCreate) {
+        return findWsseSecurityHeaderBlock(doc, envelope, null, doCreate);
+    }
+
+    /**
+     * find a ws-security header block for a given actor <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param envelope
+     *            the SOAP envelope
+     * @param actor
+     *            the acttoer (role) name of the WSS header
+     * @param doCreate
+     *            if true create a new WSS header block if none exists
+     * @return the WSS header or null if none found and doCreate is false
+     */
+    public static Element findWsseSecurityHeaderBlock(Document doc,
+            Element envelope, String actor, boolean doCreate) {
+        SOAPConstants sc = getSOAPConstants(envelope);
+        Element wsseSecurity = getSecurityHeader(doc, actor, sc);
+        if (wsseSecurity != null) {
+            return wsseSecurity;
+        }
+        Element header = findChildElement(envelope, sc.getEnvelopeURI(), sc
+                .getHeaderQName().getLocalPart());
+        if (header == null) {
+            if (doCreate) {
+                header = createElementInSameNamespace(envelope, sc
+                        .getHeaderQName().getLocalPart());
+                header = prependChildElement(doc, envelope, header, true);
+            }
+        }
+        if (doCreate) {
+            wsseSecurity = header.getOwnerDocument().createElementNS(
+                    WSConstants.WSSE_NS, "wsse:Security");
+            wsseSecurity.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsse",
+                    WSConstants.WSSE_NS);
+            return prependChildElement(doc, header, wsseSecurity, true);
+        }
+        return null;
+    }
+
+    /**
+     * create a base64 test node <p/>
+     * 
+     * @param doc
+     *            the DOM document (SOAP request)
+     * @param data
+     *            to encode
+     * @return a Text node containing the base64 encoded data
+     */
+    public static Text createBase64EncodedTextNode(Document doc, byte data[]) {
+        return doc.createTextNode(Base64.encode(data));
+    }
+
+    public static SecretKey prepareSecretKey(String symEncAlgo, byte[] rawKey) {
+        SecretKeySpec keySpec = new SecretKeySpec(rawKey, JCEMapper
+                .getJCEKeyAlgorithmFromURI(symEncAlgo));
+        return (SecretKey) keySpec;
+    }
+
+    public static SOAPConstants getSOAPConstants(Element startElement) {
+        Document doc = startElement.getOwnerDocument();
+        String ns = doc.getDocumentElement().getNamespaceURI();
+        if (WSConstants.URI_SOAP12_ENV.equals(ns)) {
+            return new SOAP12Constants();
+        } else {
+            return new SOAP11Constants();
+        }
+    }
+
+    public static Cipher getCipherInstance(String cipherAlgo)
+            throws WSSecurityException {
+        Cipher cipher = null;
+        try {
+            if (cipherAlgo.equalsIgnoreCase(WSConstants.KEYTRANSPORT_RSA15)) {
+                cipher = Cipher.getInstance("RSA/NONE/PKCS1PADDING");
+            } else if (cipherAlgo
+                    .equalsIgnoreCase(WSConstants.KEYTRANSPORT_RSAOEP)) {
+                cipher = Cipher.getInstance("RSA/NONE/OAEPPADDING");
+            } else {
+                throw new WSSecurityException(
+                        WSSecurityException.UNSUPPORTED_ALGORITHM,
+                        "unsupportedKeyTransp", new Object[] { cipherAlgo });
+            }
+        } catch (NoSuchPaddingException ex) {
+            throw new WSSecurityException(
+                    WSSecurityException.UNSUPPORTED_ALGORITHM,
+                    "unsupportedKeyTransp", new Object[] { "No such padding: "
+                            + cipherAlgo });
+        } catch (NoSuchAlgorithmException ex) {
+            throw new WSSecurityException(
+                    WSSecurityException.UNSUPPORTED_ALGORITHM,
+                    "unsupportedKeyTransp",
+                    new Object[] { "No such algorithm: " + cipherAlgo });
+        }
+        return cipher;
+    }
+
+    /**
+     * Fetch the result of a given action from a given result vector <p/>
+     * 
+     * @param wsResultVector
+     *            The result vector to fetch an action from
+     * @param action
+     *            The action to fetch
+     * @return The result fetched from the result vector, null if the result
+     *         could not be found
+     */
+    public static WSSecurityEngineResult fetchActionResult(
+            Vector wsResultVector, int action) {
+        WSSecurityEngineResult wsResult = null;
+
+        // Find the part of the security result that matches the given action
+
+        for (int i = 0; i < wsResultVector.size(); i++) {
+            // Check the result of every action whether it matches the given
+            // action
+            if (((WSSecurityEngineResult) wsResultVector.get(i)).getAction() == action) {
+                wsResult = (WSSecurityEngineResult) wsResultVector.get(i);
+            }
+        }
+
+        return wsResult;
+    }
+
+    /**
+     * Fetch the result of a given action from a given result vector <p/>
+     * 
+     * @param wsResultVector
+     *            The result vector to fetch an action from
+     * @param action
+     *            The action to fetch
+     * @param results
+     *            where to store the found results data for the action
+     * @return The result fetched from the result vector, null if the result
+     *         could not be found
+     */
+    public static Vector fetchAllActionResults(Vector wsResultVector,
+            int action, Vector results) {
+
+        // Find the parts of the security result that matches the given action
+        for (int i = 0; i < wsResultVector.size(); i++) {
+            // Check the result of every action whether it matches the given
+            // action
+            if (((WSSecurityEngineResult) wsResultVector.get(i)).getAction() == action) {
+                results.add(wsResultVector.get(i));
+            }
+        }
+        return results;
+    }
+
+    static public int decodeAction(String action, Vector actions)
+            throws WSSecurityException {
+
+        int doAction = 0;
+
+        if (action == null) {
+            return doAction;
+        }
+        String single[] = StringUtil.split(action, ' ');
+        for (int i = 0; i < single.length; i++) {
+            if (single[i].equals(WSHandlerConstants.NO_SECURITY)) {
+                doAction = WSConstants.NO_SECURITY;
+                return doAction;
+            } else if (single[i].equals(WSHandlerConstants.USERNAME_TOKEN)) {
+                doAction |= WSConstants.UT;
+                actions.add(new Integer(WSConstants.UT));
+            } else if (single[i].equals(WSHandlerConstants.SIGNATURE)) {
+                doAction |= WSConstants.SIGN;
+                actions.add(new Integer(WSConstants.SIGN));
+            } else if (single[i].equals(WSHandlerConstants.ENCRYPT)) {
+                doAction |= WSConstants.ENCR;
+                actions.add(new Integer(WSConstants.ENCR));
+            } else if (single[i].equals(WSHandlerConstants.SAML_TOKEN_UNSIGNED)) {
+                doAction |= WSConstants.ST_UNSIGNED;
+                actions.add(new Integer(WSConstants.ST_UNSIGNED));
+            } else if (single[i].equals(WSHandlerConstants.SAML_TOKEN_SIGNED)) {
+                doAction |= WSConstants.ST_SIGNED;
+                actions.add(new Integer(WSConstants.ST_SIGNED));
+            } else if (single[i].equals(WSHandlerConstants.TIMESTAMP)) {
+                doAction |= WSConstants.TS;
+                actions.add(new Integer(WSConstants.TS));
+            } else if (single[i].equals(WSHandlerConstants.NO_SERIALIZATION)) {
+                doAction |= WSConstants.NO_SERIALIZE;
+                actions.add(new Integer(WSConstants.NO_SERIALIZE));
+            } else if (single[i].equals(WSHandlerConstants.SIGN_WITH_UT_KEY)) {
+                doAction |= WSConstants.UT_SIGN;
+                actions.add(new Integer(WSConstants.UT_SIGN));
+            } else {
+                throw new WSSecurityException(
+                        "WSDoAllSender: Unknown action defined" + single[i]);
+            }
+        }
+        return doAction;
+    }
+
+    /**
+     * Returns the length of the key in # of bytes
+     * 
+     * @param algorithm
+     * @return
+     */
+    public static int getKeyLength(String algorithm) throws WSSecurityException {
+        if (algorithm.equals(WSConstants.TRIPLE_DES)) {
+            return 24;
+        } else if (algorithm.equals(WSConstants.AES_128)) {
+            return 16;
+        } else if (algorithm.equals(WSConstants.AES_192)) {
+            return 24;
+        } else if (algorithm.equals(WSConstants.AES_256)) {
+            return 32;
+        } else if (XMLSignature.ALGO_ID_MAC_HMAC_SHA1.equals(algorithm)) {
+            return 20;
+        } else if (XMLSignature.ALGO_ID_MAC_HMAC_SHA256.equals(algorithm)) {
+            return 32;
+        } else if (XMLSignature.ALGO_ID_MAC_HMAC_SHA384.equals(algorithm)) {
+            return 48;
+        } else if (XMLSignature.ALGO_ID_MAC_HMAC_SHA512.equals(algorithm)) {
+            return 64;
+        } else if (XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5
+                .equals(algorithm)) {
+            return 16;
+        } else {
+            throw new WSSecurityException(
+                    WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, null);
+        }
+    }
+
+    /**
+     * Generate a nonce of the given length
+     * 
+     * @return
+     * @throws Exception
+     */
+    public static byte[] generateNonce(int length) throws WSSecurityException {
+        try {
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] temp = new byte[length];
+            random.nextBytes(temp);
+            return temp;
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                    "Error in generating nonce of length " + length, e);
+        }
+    }
+
+    /**
+     * Search through a WSS4J results vector for a single signature covering all
+     * these elements.
+     * 
+     * @param results
+     *            results (e.g., as stored as WSHandlerConstants.RECV_RESULTS on
+     *            an Axis MessageContext)
+     * @param elements
+     *            the elements to check
+     * @return the identity of the signer
+     * @throws WSSecurityException
+     *             if no suitable signature could be found or if any element
+     *             didn't have a wsu:Id attribute
+     */
+    public static X509Certificate ensureSignedTogether(Iterator results,
+            Element[] elements) throws WSSecurityException {
+        log.debug("ensureSignedTogether()");
+
+        if (results == null)
+            throw new IllegalArgumentException("No results vector");
+        if (elements == null || elements.length == 0)
+            throw new IllegalArgumentException("No elements to check!");
+
+        // Turn the list of required elements into a list of required wsu:Id
+        // strings
+        String[] requiredIDs = new String[elements.length];
+        for (int i = 0; i < elements.length; i++) {
+            Element e = (Element) elements[i];
+            if (e == null) {
+                throw new IllegalArgumentException("elements[" + i
+                        + "] is null!");
+            }
+            requiredIDs[i] = e.getAttributeNS(WSConstants.WSU_NS, "Id");
+            if (requiredIDs[i] == null) {
+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK,
+                        "requiredElementNoID", new Object[] { e.getNodeName() });
+            }
+            log.debug("Required element " + e.getNodeName() + " has wsu:Id "
+                    + requiredIDs[i]);
+        }
+
+        WSSecurityException fault = null;
+
+        // Search through the results for a SIGN result
+        while (results.hasNext()) {
+            WSHandlerResult result = (WSHandlerResult) results.next();
+            Iterator actions = result.getResults().iterator();
+
+            while (actions.hasNext()) {
+                WSSecurityEngineResult resultItem = (WSSecurityEngineResult) actions
+                        .next();
+                if (resultItem.getAction() == WSConstants.SIGN) {
+                    try {
+                        checkSignsAllElements(resultItem, requiredIDs);
+                        return resultItem.getCertificate();
+                    } catch (WSSecurityException ex) {
+                        // Store the exception but keep going... there may be a
+                        // better signature later
+                        log
+                                .debug(
+                                        "SIGN result does not sign all required elements",
+                                        ex);
+                        fault = ex;
+                    }
+                }
+            }
+        }
+
+        if (fault != null)
+            throw fault;
+
+        throw new WSSecurityException(WSSecurityException.FAILED_CHECK,
+                "noSignResult");
+    }
+
+    /**
+     * Ensure that this signature covers all required elements (identified by
+     * their wsu:Id attributes).
+     * 
+     * @param resultItem
+     *            the signature to check
+     * @param requiredIDs
+     *            the list of wsu:Id values that must be covered
+     * @throws WSSecurityException
+     *             if any required element is not included
+     */
+    private static void checkSignsAllElements(
+            WSSecurityEngineResult resultItem, String[] requiredIDs)
+            throws WSSecurityException {
+        if (resultItem.getAction() != WSConstants.SIGN)
+            throw new IllegalArgumentException("Not a SIGN result");
+
+        Set signedIDs = resultItem.getSignedElements();
+        if (signedIDs == null)
+            throw new RuntimeException(
+                    "Missing signedElements set in WSSecurityEngineResult!");
+
+        log.debug("Found SIGN result...");
+        for (Iterator i = signedIDs.iterator(); i.hasNext();) {
+            String e = (String) i.next();
+            log.debug("Signature includes element with ID " + e);
+        }
+
+        log.debug("Checking required elements are in the signature...");
+        for (int i = 0; i < requiredIDs.length; i++) {
+            if (!signedIDs.contains(requiredIDs[i])) {
+                throw new WSSecurityException(WSSecurityException.FAILED_CHECK,
+                        "requiredElementNotSigned",
+                        new Object[] { requiredIDs[i] });
+            }
+            log.debug("Element with ID " + requiredIDs[i]
+                    + " was correctly signed");
+        }
+        log.debug("All required elements are signed");
+    }
+}
diff --git a/src/org/apache/ws/security/util/XMLUtils.java b/src/org/apache/ws/security/util/XMLUtils.java
new file mode 100644
index 0000000..0561206
--- /dev/null
+++ b/src/org/apache/ws/security/util/XMLUtils.java
@@ -0,0 +1,79 @@
+package org.apache.ws.security.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+public class XMLUtils {
+    public static String PrettyDocumentToString(Document doc) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ElementToStream(doc.getDocumentElement(), baos);
+        return new String(baos.toByteArray());
+    }
+
+    public static void ElementToStream(Element element, OutputStream out) {
+        try {
+            DOMSource source = new DOMSource(element);
+            StreamResult result = new StreamResult(out);
+            TransformerFactory transFactory = TransformerFactory.newInstance();
+            Transformer transformer = transFactory.newTransformer();
+            transformer.transform(source, result);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Utility to get the bytes uri
+     *
+     * @param source the resource to get
+     */
+    public static InputSource sourceToInputSource(Source source) {
+        if (source instanceof SAXSource) {
+            return ((SAXSource) source).getInputSource();
+        } else if (source instanceof DOMSource) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            Node node = ((DOMSource) source).getNode();
+            if (node instanceof Document) {
+                node = ((Document) node).getDocumentElement();
+            }
+            Element domElement = (Element) node;
+            ElementToStream(domElement, baos);
+            InputSource isource = new InputSource(source.getSystemId());
+            isource.setByteStream(new ByteArrayInputStream(baos.toByteArray()));
+            return isource;
+        } else if (source instanceof StreamSource) {
+            StreamSource ss = (StreamSource) source;
+            InputSource isource = new InputSource(ss.getSystemId());
+            isource.setByteStream(ss.getInputStream());
+            isource.setCharacterStream(ss.getReader());
+            isource.setPublicId(ss.getPublicId());
+            return isource;
+        } else {
+            return getInputSourceFromURI(source.getSystemId());
+        }
+    }
+
+    /**
+     * Utility to get the bytes uri.
+     * Does NOT handle authenticated URLs,
+     * use getInputSourceFromURI(uri, username, password)
+     *
+     * @param uri the resource to get
+     */
+    public static InputSource getInputSourceFromURI(String uri) {
+        return new InputSource(uri);
+    }
+}
diff --git a/src/org/apache/ws/security/util/XmlSchemaDateFormat.java b/src/org/apache/ws/security/util/XmlSchemaDateFormat.java
new file mode 100644
index 0000000..c0093a6
--- /dev/null
+++ b/src/org/apache/ws/security/util/XmlSchemaDateFormat.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright  2003-2005 The Apache Software Foundation.
+ *
+ *  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.apache.ws.security.util;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A {@link DateFormat} for the format of the dateTime simpleType as specified in the
+ * XML Schema specification. See <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">
+ * XML Schema Part 2: Datatypes, W3C Recommendation 02 May 2001, Section 3.2.7.1</a>.
+ *
+ * @author Ian P. Springer
+ * @author Werner Dittmann
+ */
+public class XmlSchemaDateFormat extends DateFormat {
+	/**
+	 * Logger.
+	 */
+	private static Log log = LogFactory.getLog(XmlSchemaDateFormat.class);
+
+	private static boolean doDebug = false;
+
+	static {
+		doDebug = log.isDebugEnabled();
+	}
+
+	/**
+	 * Message retriever.
+	 */
+	//   private static final MessageRetriever MSG = ResourceKeys.MSG;
+	/**
+	 * DateFormat for Zulu (UTC) form of an XML Schema dateTime string.
+	 */
+	private static final DateFormat DATEFORMAT_XSD_ZULU = new SimpleDateFormat(
+			"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+	static {
+		DATEFORMAT_XSD_ZULU.setTimeZone(TimeZone.getTimeZone("UTC"));
+	}
+
+	/**
+	 * This method was snarfed from <tt>org.apache.axis.encoding.ser.CalendarDeserializer</tt>,
+	 * which was written by Sam Ruby (rubys@us.ibm.com) and Rich Scheuerle (scheu@us.ibm.com).
+	 * Better error reporting was added.
+	 *
+	 * @see DateFormat#parse(java.lang.String)
+	 */
+	public Date parse(String src, ParsePosition parse_pos) {
+		Date date;
+
+		// validate fixed portion of format
+		int index = 0;
+		try {
+			if (src != null) {
+				if ((src.charAt(0) == '+') || (src.charAt(0) == '-')) {
+					src = src.substring(1);
+				}
+
+				if (src.length() < 19) {
+					parse_pos.setIndex(src.length() - 1);
+					handleParseError(parse_pos, "TOO_FEW_CHARS");
+				}
+				validateChar(src, parse_pos, index = 4, '-', "EXPECTED_DASH");
+				validateChar(src, parse_pos, index = 7, '-', "EXPECTED_DASH");
+				validateChar(src, parse_pos, index = 10, 'T', "EXPECTED_CAPITAL_T");
+				validateChar(src, parse_pos, index = 13, ':', "EXPECTED_COLON_IN_TIME");
+				validateChar(src, parse_pos, index = 16, ':', "EXPECTED_COLON_IN_TIME");
+			}
+
+			// convert what we have validated so far
+			try {
+				synchronized (DATEFORMAT_XSD_ZULU) {
+					date = DATEFORMAT_XSD_ZULU.parse((src == null) ? null
+							: (src.substring(0, 19) + ".000Z"));
+				}
+			} catch (Exception e) {
+				throw new NumberFormatException(e.toString());
+			}
+
+			index = 19;
+
+			// parse optional milliseconds
+			if (src != null) {
+				if ((index < src.length()) && (src.charAt(index) == '.')) {
+					int milliseconds = 0;
+					int start = ++index;
+
+					while ((index < src.length())
+							&& Character.isDigit(src.charAt(index))) {
+						index++;
+					}
+
+					String decimal = src.substring(start, index);
+
+					if (decimal.length() == 3) {
+						milliseconds = Integer.parseInt(decimal);
+					} else if (decimal.length() < 3) {
+						milliseconds = Integer.parseInt((decimal + "000")
+								.substring(0, 3));
+					} else {
+						milliseconds = Integer
+								.parseInt(decimal.substring(0, 3));
+
+						if (decimal.charAt(3) >= '5') {
+							++milliseconds;
+						}
+					}
+
+					// add milliseconds to the current date
+					date.setTime(date.getTime() + milliseconds);
+				}
+
+				// parse optional timezone
+				if (((index + 5) < src.length())
+						&& ((src.charAt(index) == '+') || (src.charAt(index) == '-'))) {
+					validateCharIsDigit(src, parse_pos, index + 1, "EXPECTED_NUMERAL");
+					validateCharIsDigit(src, parse_pos, index + 2, "EXPECTED_NUMERAL");
+					validateChar(src, parse_pos, index + 3, ':', "EXPECTED_COLON_IN_TIMEZONE");
+					validateCharIsDigit(src, parse_pos, index + 4, "EXPECTED_NUMERAL");
+					validateCharIsDigit(src, parse_pos, index + 5, "EXPECTED_NUMERAL");
+
+					final int hours = (((src.charAt(index + 1) - '0') * 10) + src
+							.charAt(index + 2)) - '0';
+					final int mins = (((src.charAt(index + 4) - '0') * 10) + src
+							.charAt(index + 5)) - '0';
+					int millisecs = ((hours * 60) + mins) * 60 * 1000;
+
+					// subtract millisecs from current date to obtain GMT
+					if (src.charAt(index) == '+') {
+						millisecs = -millisecs;
+					}
+
+					date.setTime(date.getTime() + millisecs);
+					index += 6;
+				}
+
+				if ((index < src.length()) && (src.charAt(index) == 'Z')) {
+					index++;
+				}
+
+				if (index < src.length()) {
+					handleParseError(parse_pos, "TOO_MANY_CHARS");
+				}
+			}
+		} catch (ParseException pe) {
+			log.error(pe.toString());
+			index = 0; // IMPORTANT: this tells DateFormat.parse() to throw a ParseException
+			parse_pos.setErrorIndex(index);
+			date = null;
+		}
+		parse_pos.setIndex(index);
+		return (date);
+	}
+
+	/**
+	 * @see DateFormat#format(java.util.Date)
+	 */
+	public StringBuffer format(Date date, StringBuffer append_buf,
+			FieldPosition field_pos) {
+		String str;
+
+		synchronized (DATEFORMAT_XSD_ZULU) {
+			str = DATEFORMAT_XSD_ZULU.format(date);
+		}
+
+		if (append_buf == null) {
+			append_buf = new StringBuffer();
+		}
+
+		append_buf.append(str);
+
+		return (append_buf);
+	}
+
+	private void validateChar(String str, ParsePosition parse_pos, int index,
+			char expected, String error_reason) throws ParseException {
+		if (str.charAt(index) != expected) {
+			handleParseError(parse_pos, error_reason);
+		}
+	}
+
+	private void validateCharIsDigit(String str, ParsePosition parse_pos,
+			int index, String error_reason) throws ParseException {
+		if (!Character.isDigit(str.charAt(index))) {
+			handleParseError(parse_pos, error_reason);
+		}
+	}
+
+	private void handleParseError(ParsePosition parse_pos, String error_reason)
+			throws ParseException {
+		throw new ParseException("INVALID_XSD_DATETIME", parse_pos.getErrorIndex());
+	}
+
+}
diff --git a/src/saml.properties b/src/saml.properties
new file mode 100644
index 0000000..f4cf83f
--- /dev/null
+++ b/src/saml.properties
@@ -0,0 +1,12 @@
+org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.SAMLIssuerImpl
+org.apache.ws.security.saml.issuer.cryptoProp.file=crypto.properties
+org.apache.ws.security.saml.issuer.key.name=16c73ab6-b892-458f-abf5-2f875f74882e
+org.apache.ws.security.saml.issuer.key.password=security
+org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
+org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
+org.apache.ws.security.saml.authenticationMethod=password
+org.apache.ws.security.saml.confirmationMethod=senderVouches
+#org.apache.ws.security.saml.confirmationMethod=keyHolder
+#org.apache.ws.security.saml
+#org.apache.ws.security.saml
diff --git a/src/saml3.properties b/src/saml3.properties
new file mode 100644
index 0000000..f4cf83f
--- /dev/null
+++ b/src/saml3.properties
@@ -0,0 +1,12 @@
+org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.SAMLIssuerImpl
+org.apache.ws.security.saml.issuer.cryptoProp.file=crypto.properties
+org.apache.ws.security.saml.issuer.key.name=16c73ab6-b892-458f-abf5-2f875f74882e
+org.apache.ws.security.saml.issuer.key.password=security
+org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
+org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
+org.apache.ws.security.saml.authenticationMethod=password
+org.apache.ws.security.saml.confirmationMethod=senderVouches
+#org.apache.ws.security.saml.confirmationMethod=keyHolder
+#org.apache.ws.security.saml
+#org.apache.ws.security.saml
diff --git a/src/saml4.properties b/src/saml4.properties
new file mode 100644
index 0000000..3ac8d12
--- /dev/null
+++ b/src/saml4.properties
@@ -0,0 +1,12 @@
+org.apache.ws.security.saml.issuerClass=org.apache.ws.security.saml.SAMLIssuerImpl
+org.apache.ws.security.saml.issuer.cryptoProp.file=crypto.properties
+org.apache.ws.security.saml.issuer.key.name=16c73ab6-b892-458f-abf5-2f875f74882e
+org.apache.ws.security.saml.issuer.key.password=security
+org.apache.ws.security.saml.issuer=www.example.com
+org.apache.ws.security.saml.subjectNameId.name=uid=joe,ou=people,ou=saml-demo,o=example.com
+org.apache.ws.security.saml.subjectNameId.qualifier=www.example.com
+org.apache.ws.security.saml.authenticationMethod=password
+#org.apache.ws.security.saml.confirmationMethod=senderVouches
+org.apache.ws.security.saml.confirmationMethod=keyHolder
+#org.apache.ws.security.saml
+#org.apache.ws.security.saml
diff --git a/test/components/PackageTests.java b/test/components/PackageTests.java
new file mode 100644
index 0000000..db5c240
--- /dev/null
+++ b/test/components/PackageTests.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 components;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test package for WS-Security tests
+ */
+public class PackageTests extends TestCase {
+
+    public PackageTests(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(TestMerlin.class);
+        return suite;
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+}
diff --git a/test/components/TestMerlin.java b/test/components/TestMerlin.java
new file mode 100644
index 0000000..87508f4
--- /dev/null
+++ b/test/components/TestMerlin.java
@@ -0,0 +1,41 @@
+package components;
+
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.components.crypto.Crypto;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: srida01
+ * Date: Apr 12, 2004
+ * Time: 10:50:05 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TestMerlin extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestMerlin(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestMerlin.class);
+    }
+
+    public void testCrypto() {
+        Crypto crypto = CryptoFactory.getInstance();
+        assertTrue(crypto != null);
+    }
+}
diff --git a/test/interop/PackageTests.java b/test/interop/PackageTests.java
new file mode 100644
index 0000000..b43ce0b
--- /dev/null
+++ b/test/interop/PackageTests.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test package for WS-Security tests
+ */
+public class PackageTests extends TestCase {
+
+    public PackageTests(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(TestInteropKeys.class);
+        suite.addTestSuite(TestScenario1.class);
+        suite.addTestSuite(TestScenario2.class);
+        suite.addTestSuite(TestScenario2a.class);
+        suite.addTestSuite(TestScenario3.class);
+        suite.addTestSuite(TestScenario4.class);
+        suite.addTestSuite(TestScenario5.class);
+        suite.addTestSuite(TestScenario6.class); 
+        suite.addTestSuite(TestScenario7.class); 
+        suite.addTestSuite(TestSTScenario1.class);
+        suite.addTestSuite(TestSTScenario3.class);
+        suite.addTestSuite(TestSTScenario4.class);
+        return suite;
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+}
diff --git a/test/interop/TestInteropKeys.java b/test/interop/TestInteropKeys.java
new file mode 100644
index 0000000..3b087b8
--- /dev/null
+++ b/test/interop/TestInteropKeys.java
@@ -0,0 +1,57 @@
+package interop;
+
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+
+import java.security.cert.X509Certificate;
+import java.security.PrivateKey;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: srida01
+ * Date: Mar 15, 2004
+ * Time: 10:47:59 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TestInteropKeys extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestInteropKeys(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestInteropKeys.class);
+    }
+
+    public void testInteropKeys1() throws Exception {
+        Crypto c = CryptoFactory.getInstance("wsstest.properties");
+        X509Certificate[] certs = c.getCertificates("alice");
+        assertTrue(certs != null);
+        assertTrue(certs[0] != null);
+        PrivateKey privKey = c.getPrivateKey("alice","password");
+        assertTrue(privKey != null);
+    }
+
+    public void testInteropKeys2() throws Exception {
+        Crypto c = CryptoFactory.getInstance("wsstest.properties");
+        X509Certificate[] certs = c.getCertificates("bob");
+        assertTrue(certs != null);
+        assertTrue(certs[0] != null);
+        PrivateKey privKey = c.getPrivateKey("bob","password");
+        assertTrue(privKey != null);
+    }
+}
diff --git a/test/interop/TestJAXRPCHandler.java b/test/interop/TestJAXRPCHandler.java
new file mode 100755
index 0000000..f5d7a90
--- /dev/null
+++ b/test/interop/TestJAXRPCHandler.java
@@ -0,0 +1,147 @@
+package interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.ping.PingPort;
+import org.apache.ws.axis.oasis.ping.PingServiceLocator;
+import org.apache.ws.security.handler.WSS4JHandler;
+
+import javax.xml.namespace.QName;
+import javax.xml.rpc.handler.HandlerInfo;
+import javax.xml.rpc.handler.HandlerRegistry;
+import javax.xml.rpc.holders.StringHolder;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TestJAXRPCHandler extends TestCase {
+    /**
+     * @param name name of the test
+     */
+    public TestJAXRPCHandler(String name) {
+        super(name);
+    }
+
+    /**
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestJAXRPCHandler.class);
+    }
+
+    public void testScenario1() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("flow", "request-only");
+        config.put("action", "UsernameToken");
+        config.put("user", "Chris");
+        config.put("passwordType", "PasswordText");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        invokeService (config, 1);
+    }
+    public void testScenario2() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("flow", "request-only");
+        config.put("user", "Chris");
+        config.put("passwordType", "PasswordText");
+        config.put("action", "UsernameToken Encrypt");
+        config.put("addUTElements", "Nonce Created");
+        config.put("encryptionPropFile", "wsstest.properties");
+        config.put("encryptionKeyIdentifier", "SKIKeyIdentifier");
+        config.put("encryptionUser", "bob");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("encryptionParts", "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken");  
+        invokeService (config, 2);
+    }
+    public void testScenario3() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("action", "Signature Encrypt Timestamp");
+        config.put("user", "alice");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("signatureKeyIdentifier", "DirectReference");
+        config.put("signaturePropFile", "wsstest.properties");
+        config.put("encryptionKeyIdentifier", "SKIKeyIdentifier");
+        config.put("encryptionUser", "bob");
+        invokeService (config, 3);
+    }
+    public void testScenario4() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("action", "Signature Encrypt Timestamp");
+        config.put("user", "alice");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("signatureKeyIdentifier", "DirectReference");
+        config.put("signaturePropFile", "wsstest.properties");
+        config.put("encryptionKeyIdentifier", "EmbeddedKeyName");
+        config.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
+        config.put("EmbeddedKeyCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("EmbeddedKeyName", "SessionKey");
+        invokeService (config, 4);
+    }
+    
+    // testScenario5 - Ping5 fails because there is now way in JAXRPC to 
+    // specifiy the parameter signatureKeyIdentifier with different values 
+    // for request and response flows
+/*    public void testScenario5() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("action", "Signature NoSerialization");
+        config.put("user", "alice");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("signatureKeyIdentifier", "DirectReference");
+        config.put("signaturePropFile", "wsstest.properties");
+        config.put("signatureParts", "{}{http://xmlsoap.org/Ping}ticket");
+        invokeService (config, 5);
+    }
+*/    public void testScenario6() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("action", "Encrypt Signature Timestamp");
+        config.put("user", "alice");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("signatureKeyIdentifier", "DirectReference");
+        config.put("signaturePropFile", "wsstest.properties");
+        config.put("encryptionKeyIdentifier", "SKIKeyIdentifier");
+        config.put("encryptionUser", "bob");
+        invokeService (config, 6);
+    }
+    public void testScenario7() throws Exception {
+        Map config = new HashMap();
+        config.put("deployment", "client");
+        config.put("action", "Signature Encrypt Timestamp");
+        config.put("user", "alice");
+        config.put("passwordCallbackClass", "org.apache.ws.axis.oasis.PWCallback1");
+        config.put("signatureKeyIdentifier", "DirectReference");
+        config.put("signaturePropFile", "wsstest.properties");
+        config.put("encryptionKeyIdentifier", "SKIKeyIdentifier");
+        config.put("encryptionUser", "bob");
+        config.put("encryptionPropFile", "wsstest.properties");
+        config.put("signatureParts", "{}{http://schemas.xmlsoap.org/soap/envelope/}Body;STRTransform");
+        invokeService (config, 7);
+    }
+    
+    public void invokeService (Map config, int interopNum) throws Exception {
+        PingServiceLocator service = new PingServiceLocator();
+
+        List handlerChain = new ArrayList();
+        handlerChain.add(new HandlerInfo( WSS4JHandler.class, config, null));
+
+        HandlerRegistry registry = service.getHandlerRegistry();
+        registry.setHandlerChain(new QName("Ping" + interopNum), handlerChain);
+
+        service.getHandlerRegistry().getHandlerChain(new QName("http://xmlsoap.org/Ping", "ticketType"));
+        
+        java.lang.reflect.Method method = service.getClass().getMethod("getPing" + interopNum, new Class[] {URL.class});
+
+        PingPort port = (PingPort) method.invoke (service, new Object[] {new URL("http://localhost:8080/axis/services/Ping" + interopNum)});
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario" + interopNum + " @ [" + new java.util.Date(System.currentTimeMillis()) + "]");
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J" + interopNum), text);
+        System.out.println(text.value);
+    }
+}
diff --git a/test/interop/TestSTScenario1.java b/test/interop/TestSTScenario1.java
new file mode 100644
index 0000000..2b052ee
--- /dev/null
+++ b/test/interop/TestSTScenario1.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.STScenario1;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestSTScenario1 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestSTScenario1(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestSTScenario1.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        STScenario1.main(args);
+    }
+
+    public void testSTScenario1() throws Exception {
+        STScenario1.main(new String[]{"-lhttp://localhost:8080/axis/services/STPing1"});
+    }
+}
diff --git a/test/interop/TestSTScenario2.java b/test/interop/TestSTScenario2.java
new file mode 100644
index 0000000..5bcdded
--- /dev/null
+++ b/test/interop/TestSTScenario2.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.STScenario1;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestSTScenario2 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestSTScenario2(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestSTScenario2.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        STScenario1.main(args);
+    }
+
+    public void testSTScenario1() throws Exception {
+        STScenario1.main(new String[]{"-lhttp://localhost:8080/axis/services/STPing1"});
+    }
+}
diff --git a/test/interop/TestSTScenario3.java b/test/interop/TestSTScenario3.java
new file mode 100644
index 0000000..b772e12
--- /dev/null
+++ b/test/interop/TestSTScenario3.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.STScenario3;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestSTScenario3 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestSTScenario3(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestSTScenario3.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        STScenario3.main(args);
+    }
+
+    public void testSTScenario3() throws Exception {
+        STScenario3.main(new String[]{"-lhttp://localhost:8080/axis/services/STPing3"});
+    }
+}
diff --git a/test/interop/TestSTScenario4.java b/test/interop/TestSTScenario4.java
new file mode 100644
index 0000000..96a5e7a
--- /dev/null
+++ b/test/interop/TestSTScenario4.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.STScenario4;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestSTScenario4 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestSTScenario4(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestSTScenario4.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        STScenario4.main(args);
+    }
+
+    public void testSTScenario4() throws Exception {
+        STScenario4.main(new String[]{"-lhttp://localhost:8080/axis/services/STPing4"});
+    }
+}
diff --git a/test/interop/TestScenario1.java b/test/interop/TestScenario1.java
new file mode 100644
index 0000000..f9cd7ed
--- /dev/null
+++ b/test/interop/TestScenario1.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario1;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario1 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario1(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario1.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario1.main(args);
+    }
+
+    public void testScenario1() throws Exception {
+        Scenario1.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping1"});
+    }
+}
diff --git a/test/interop/TestScenario2.java b/test/interop/TestScenario2.java
new file mode 100644
index 0000000..d138968
--- /dev/null
+++ b/test/interop/TestScenario2.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario2;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario2 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario2(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario2.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario2.main(args);
+    }
+
+    public void testScenario2() throws Exception {
+        Scenario2.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping2"});
+    }
+}
diff --git a/test/interop/TestScenario2a.java b/test/interop/TestScenario2a.java
new file mode 100644
index 0000000..7fd5a84
--- /dev/null
+++ b/test/interop/TestScenario2a.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario2a;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario2a extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario2a(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario2a.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario2a.main(args);
+    }
+
+    public void testScenario2a() throws Exception {
+        Scenario2a.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping2a"});
+    }
+}
diff --git a/test/interop/TestScenario3.java b/test/interop/TestScenario3.java
new file mode 100644
index 0000000..ba208c0
--- /dev/null
+++ b/test/interop/TestScenario3.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario3;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario3 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario3(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario3.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+         Scenario3.main(args);
+    }
+
+    public void testScenario3() throws Exception {
+        Scenario3.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping3"});
+    }
+}
diff --git a/test/interop/TestScenario4.java b/test/interop/TestScenario4.java
new file mode 100644
index 0000000..dc2ae07
--- /dev/null
+++ b/test/interop/TestScenario4.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario4;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario4 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario4(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario4.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario4.main(args);
+    }
+
+    public void testScenario4() throws Exception {
+        Scenario4.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping4"});
+    }
+}
diff --git a/test/interop/TestScenario5.java b/test/interop/TestScenario5.java
new file mode 100644
index 0000000..c192af8
--- /dev/null
+++ b/test/interop/TestScenario5.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario5;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario5 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario5(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario5.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario5.main(args);
+    }
+
+    public void testScenario5() throws Exception {
+        Scenario5.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping5"});
+    }
+}
diff --git a/test/interop/TestScenario6.java b/test/interop/TestScenario6.java
new file mode 100644
index 0000000..77007bc
--- /dev/null
+++ b/test/interop/TestScenario6.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario6;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario6 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario6(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario6.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario6.main(args);
+    }
+
+    public void testScenario6() throws Exception {
+        Scenario6.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping6"});
+    }
+}
diff --git a/test/interop/TestScenario7.java b/test/interop/TestScenario7.java
new file mode 100644
index 0000000..c327994
--- /dev/null
+++ b/test/interop/TestScenario7.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 interop;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.ws.axis.oasis.Scenario7;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestScenario7 extends TestCase {
+    /**
+     * TestScenario1 constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestScenario7(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestScenario7.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) throws Exception {
+        Scenario7.main(args);
+    }
+
+    public void testScenario7() throws Exception {
+        Scenario7.main(new String[]{"-lhttp://localhost:8080/axis/services/Ping7"});
+    }
+}
diff --git a/test/policy/SecurityPolicyBindings.xml b/test/policy/SecurityPolicyBindings.xml
new file mode 100644
index 0000000..abcecbd
--- /dev/null
+++ b/test/policy/SecurityPolicyBindings.xml
@@ -0,0 +1,50 @@
+
+<!-- Example Endpoint Policy --> 
+<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+            xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
+            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+<sp:AsymmetricBinding>
+ <wsp:Policy>
+ <sp:RecipientToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" />
+ </wsp:Policy> </sp:RecipientToken>
+ <sp:InitiatorToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" />
+ </wsp:Policy>
+ </sp:InitiatorToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptBeforeSigning />
+ <sp:EncryptSignature />
+ <sp:ProtectTokens />
+ <sp:SignedSupportingTokens>
+ <wsp:Policy>
+ <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once" />
+ </wsp:Policy>
+ </sp:SignedSupportingTokens>
+ <sp:SignedEndorsingSupportingTokens>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once" />
+ </wsp:Policy>
+ </sp:SignedEndorsingSupportingTokens>
+ </wsp:Policy> 
+ </sp:AsymmetricBinding>
+ <sp:Wss11> 
+ <wsp:Policy>
+ <sp:RequireSignatureConfirmation />
+ </wsp:Policy>
+ </sp:Wss11>
+ </wsp:Policy>
+
+ 
\ No newline at end of file
diff --git a/test/policy/SecurityPolicyBindingsAsymmTest.xml b/test/policy/SecurityPolicyBindingsAsymmTest.xml
new file mode 100644
index 0000000..e751378
--- /dev/null
+++ b/test/policy/SecurityPolicyBindingsAsymmTest.xml
@@ -0,0 +1,73 @@
+
+<!-- Example Endpoint Policy --> 
+<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+            xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
+            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+<sp:AsymmetricBinding>
+  <wsp:Policy>
+    <sp:RecipientToken>
+      <wsp:Policy>
+        <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" >
+          <wsp:Policy>
+            <sp:RequireIssuerSerialReference />
+          </wsp:Policy>
+        </sp:X509Token>
+      </wsp:Policy> 
+    </sp:RecipientToken>
+    <sp:InitiatorToken>
+      <wsp:Policy>
+        <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" >
+          <wsp:Policy>
+            <sp:RequireIssuerSerialReference />
+          </wsp:Policy>
+        </sp:X509Token>
+      </wsp:Policy>
+    </sp:InitiatorToken>
+    <sp:AlgorithmSuite>
+      <wsp:Policy>
+        <sp:Basic256 />
+      </wsp:Policy>
+    </sp:AlgorithmSuite>
+    <sp:Layout>
+      <wsp:Policy>
+        <sp:Strict />
+      </wsp:Policy>
+    </sp:Layout>
+    <sp:IncludeTimestamp />
+    <sp:EncryptBeforeSigning />
+    <sp:EncryptSignature />
+    <sp:ProtectTokens />
+  </wsp:Policy> 
+</sp:AsymmetricBinding>
+<sp:Wss11> 
+  <wsp:Policy>
+    <sp:RequireSignatureConfirmation />
+  </wsp:Policy>
+</sp:Wss11>
+<sp:SignedSupportingTokens>
+  <wsp:Policy>
+    <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once" />
+    <sp:AlgorithmSuite>
+      <wsp:Policy>
+        <sp:Basic256 />
+      </wsp:Policy>
+    </sp:AlgorithmSuite>
+  </wsp:Policy>
+</sp:SignedSupportingTokens>
+<sp:SignedEndorsingSupportingTokens>
+  <wsp:Policy>
+    <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" >
+      <wsp:Policy>
+        <sp:RequireIssuerSerialReference />
+      </wsp:Policy>
+    </sp:X509Token>
+    <sp:AlgorithmSuite>
+      <wsp:Policy>
+        <sp:Basic256 />
+      </wsp:Policy>
+    </sp:AlgorithmSuite>
+  </wsp:Policy>
+</sp:SignedEndorsingSupportingTokens>
+</wsp:Policy>
+
+ 
\ No newline at end of file
diff --git a/test/policy/SecurityPolicyBindingsSymm.xml b/test/policy/SecurityPolicyBindingsSymm.xml
new file mode 100644
index 0000000..9577ee3
--- /dev/null
+++ b/test/policy/SecurityPolicyBindingsSymm.xml
@@ -0,0 +1,43 @@
+<!-- Example Endpoint Policy -->

+<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"

+            xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"

+            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

+<sp:SymmetricBinding>

+<wsp:Policy>

+<sp:ProtectionToken>
+<wsp:Policy>

+<sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always"/>
+</wsp:Policy>

+</sp:ProtectionToken>

+<sp:AlgorithmSuite>

+<wsp:Policy>

+<sp:Basic256 />

+</wsp:Policy>

+</sp:AlgorithmSuite>

+<sp:Layout>

+<wsp:Policy>

+<sp:Strict />

+</wsp:Policy>

+</sp:Layout>

+<sp:IncludeTimestamp />

+<sp:EncryptBeforeSigning />

+<sp:EncryptSignature />

+<sp:ProtectTokens />

+<sp:SignedSupportingTokens>

+<wsp:Policy>

+<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Once" />

+</wsp:Policy>

+</sp:SignedSupportingTokens>

+<!--<sp:SignedEndorsingSupportingTokens>

+<wsp:Policy>

+<sp:X509V3Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/IncludeToken/Once" />

+</wsp:Policy>

+</sp:SignedEndorsingSupportingTokens> -->

+</wsp:Policy>

+</sp:SymmetricBinding>

+<sp:Wss11>

+<wsp:Policy>

+<sp:RequireSignatureConfirmation />

+</wsp:Policy>

+</sp:Wss11>

+</wsp:Policy>

diff --git a/test/policy/SecurityPolicyMsg.xml b/test/policy/SecurityPolicyMsg.xml
new file mode 100644
index 0000000..b2be5fd
--- /dev/null
+++ b/test/policy/SecurityPolicyMsg.xml
@@ -0,0 +1,19 @@
+<!-- Example Endpoint Policy --> 
+<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+            xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
+            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+
+ <!-- Example Message Policy -->
+
+ <sp:SignedParts>
+   <sp:Header Name="Header1" Namespace="uri:namespace_1" />
+   <sp:Header Name="Header2" Namespace="uri:namespace_2" /> 
+   <sp:Body/>
+ </sp:SignedParts>
+ <sp:EncryptedParts>
+   <sp:Header Name="Header2" Namespace="uri:namespace_2" />
+   <sp:Body/>
+ </sp:EncryptedParts>
+
+ </wsp:Policy>
+ 
\ No newline at end of file
diff --git a/test/policy/SecurityPolicyMsgTest.xml b/test/policy/SecurityPolicyMsgTest.xml
new file mode 100644
index 0000000..b2be5fd
--- /dev/null
+++ b/test/policy/SecurityPolicyMsgTest.xml
@@ -0,0 +1,19 @@
+<!-- Example Endpoint Policy --> 
+<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
+            xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"
+            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
+
+ <!-- Example Message Policy -->
+
+ <sp:SignedParts>
+   <sp:Header Name="Header1" Namespace="uri:namespace_1" />
+   <sp:Header Name="Header2" Namespace="uri:namespace_2" /> 
+   <sp:Body/>
+ </sp:SignedParts>
+ <sp:EncryptedParts>
+   <sp:Header Name="Header2" Namespace="uri:namespace_2" />
+   <sp:Body/>
+ </sp:EncryptedParts>
+
+ </wsp:Policy>
+ 
\ No newline at end of file
diff --git a/test/policy/WSSPolicyProcessorTest.java b/test/policy/WSSPolicyProcessorTest.java
new file mode 100644
index 0000000..5731fb8
--- /dev/null
+++ b/test/policy/WSSPolicyProcessorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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 policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.model.PolicyEngineData;
+import org.apache.ws.security.policy.model.RootPolicyEngineData;
+import org.apache.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.ws.security.policy.model.SymmetricBinding;
+import org.apache.ws.security.policy.model.Wss11;
+import org.apache.ws.security.policy.parser.WSSPolicyProcessor;
+
+public class WSSPolicyProcessorTest extends TestCase {
+
+    public WSSPolicyProcessorTest(String name) {
+        super(name);
+    }
+
+    public void testSymmetricBinding() {
+        try {
+            WSSPolicyProcessor processor = new WSSPolicyProcessor();
+            if (!processor.setup()) {
+                return;
+            }
+            String[] files = new String[2];
+            files[0] = "test/policy/SecurityPolicyBindingsSymm.xml";
+            files[1] = "test/policy/SecurityPolicyMsg.xml";
+            processor.go(files);
+            
+            RootPolicyEngineData rootPolicyEngineData = (RootPolicyEngineData)processor.secProcessorContext.getPedStack().get(0);
+            assertNotNull("RootPolicyEngineData missing", rootPolicyEngineData);
+            
+            ArrayList peds = rootPolicyEngineData.getTopLevelPEDs();
+            assertEquals("Incrrect number of PolicyEngineData", 4, peds.size());
+            
+            Iterator pedIter = peds.iterator();
+            boolean symmBindingfound = false, wss11found = false, signedPartsFound = false, encryptedPartsFound = false;
+            while (pedIter.hasNext()) {
+                PolicyEngineData ped = (PolicyEngineData) pedIter.next();
+                if(ped instanceof SymmetricBinding) {
+                    symmBindingfound = true;
+                    SymmetricBinding symmetricBinding = (SymmetricBinding)ped;
+                    assertEquals("Incorrect layout",Constants.LAYOUT_STRICT ,symmetricBinding.getLayout().getValue());
+                } else if(ped instanceof Wss11) {
+                    wss11found = true;
+                    Wss11 wss11 = (Wss11)ped;
+                    assertEquals("Signature confirmation must be true", true,
+                            wss11.isRequireSignatureConfirmation());
+                } else if(ped instanceof SignedEncryptedParts) {
+                    SignedEncryptedParts parts = (SignedEncryptedParts)ped;
+                    if(parts.isSignedParts()) {
+                        signedPartsFound = true;
+                        assertEquals(
+                                "Incorrect number of headers in SignedParts",
+                                2, parts.getHeaders().size());
+                    } else {
+                        encryptedPartsFound = true;
+                        assertEquals(
+                                "Incorrect number of headers in EncryptedParts",
+                                1, parts.getHeaders().size());
+                    }
+                }
+            }
+            assertTrue("SignedParts missing", signedPartsFound);
+            assertTrue("EncryptedParts missing", encryptedPartsFound);
+            assertTrue("SymmetricBinding missing", symmBindingfound);
+            assertTrue("Wss11 missing", wss11found);
+            System.out.println("Success");
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+}
diff --git a/test/policy/WSSPolicyProcessorTestAsymm.java b/test/policy/WSSPolicyProcessorTestAsymm.java
new file mode 100644
index 0000000..e331568
--- /dev/null
+++ b/test/policy/WSSPolicyProcessorTestAsymm.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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 policy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.model.PolicyEngineData;
+import org.apache.ws.security.policy.model.RootPolicyEngineData;
+import org.apache.ws.security.policy.model.SignedEncryptedParts;
+import org.apache.ws.security.policy.model.AsymmetricBinding;
+import org.apache.ws.security.policy.model.Wss11;
+import org.apache.ws.security.policy.parser.WSSPolicyProcessor;
+
+public class WSSPolicyProcessorTestAsymm extends TestCase {
+
+    public WSSPolicyProcessorTestAsymm(String name) {
+        super(name);
+    }
+
+    public void testAsymmetricBinding() {
+        try {
+            WSSPolicyProcessor processor = new WSSPolicyProcessor();
+            if (!processor.setup()) {
+                return;
+            }
+            String[] files = new String[2];
+            files[0] = "test/policy/SecurityPolicyBindings.xml";
+            files[1] = "test/policy/SecurityPolicyMsg.xml";
+            processor.go(files);
+            
+            RootPolicyEngineData rootPolicyEngineData = (RootPolicyEngineData)processor.secProcessorContext.getPedStack().get(0);
+            assertNotNull("RootPolicyEngineData missing", rootPolicyEngineData);
+            
+            ArrayList peds = rootPolicyEngineData.getTopLevelPEDs();
+            assertEquals("Incrrect number of PolicyEngineData", 4, peds.size());
+            
+            Iterator pedIter = peds.iterator();
+            boolean asymmBindingfound = false, wss11found = false, signedPartsFound = false, encryptedPartsFound = false;
+            while (pedIter.hasNext()) {
+                PolicyEngineData ped = (PolicyEngineData) pedIter.next();
+                if(ped instanceof AsymmetricBinding) {
+                    asymmBindingfound = true;
+                    AsymmetricBinding symmetricBinding = (AsymmetricBinding)ped;
+                    assertEquals("Incorrect layout",Constants.LAYOUT_STRICT ,symmetricBinding.getLayout().getValue());
+                } else if(ped instanceof Wss11) {
+                    wss11found = true;
+                    Wss11 wss11 = (Wss11)ped;
+                    assertEquals("Signature confirmation must be true", true,
+                            wss11.isRequireSignatureConfirmation());
+                } else if(ped instanceof SignedEncryptedParts) {
+                    SignedEncryptedParts parts = (SignedEncryptedParts)ped;
+                    if(parts.isSignedParts()) {
+                        signedPartsFound = true;
+                        assertEquals(
+                                "Incorrect number of headers in SignedParts",
+                                2, parts.getHeaders().size());
+                    } else {
+                        encryptedPartsFound = true;
+                        assertEquals(
+                                "Incorrect number of headers in EncryptedParts",
+                                1, parts.getHeaders().size());
+                    }
+                }
+            }
+            assertTrue("SignedParts missing", signedPartsFound);
+            assertTrue("EncryptedParts missing", encryptedPartsFound);
+            assertTrue("AsymmetricBinding missing", asymmBindingfound);
+            assertTrue("Wss11 missing", wss11found);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+}
diff --git a/test/policy/WSSPolicyTesterAsymm.java b/test/policy/WSSPolicyTesterAsymm.java
new file mode 100644
index 0000000..d8f6d1f
--- /dev/null
+++ b/test/policy/WSSPolicyTesterAsymm.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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 policy;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecEncrypt;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecTimestamp;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.policy.Constants;
+import org.apache.ws.security.policy.WSS4JPolicyBuilder;
+import org.apache.ws.security.policy.WSS4JPolicyData;
+import org.apache.ws.security.policy.WSS4JPolicyToken;
+import org.apache.ws.security.policy.WSSPolicyException;
+import org.apache.ws.security.policy.model.RootPolicyEngineData;
+import org.apache.ws.security.policy.parser.WSSPolicyProcessor;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import wssec.SOAPUtil;
+
+public class WSSPolicyTesterAsymm extends TestCase implements CallbackHandler {
+	private static Log log = LogFactory.getLog(WSSPolicyTesterAsymm.class);
+
+	static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+			+ "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+			+ "   <soapenv:Body>"
+			+ "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>"
+			+ "   </soapenv:Body>" + "</soapenv:Envelope>";
+
+	static final WSSecurityEngine secEngine = new WSSecurityEngine();
+
+	static final Crypto crypto = CryptoFactory.getInstance();
+
+	static final Crypto cryptoSKI = CryptoFactory
+			.getInstance("cryptoSKI.properties");
+
+	MessageContext msgContext;
+
+	Message message;
+
+	/**
+	 * Policy Tester constructor.
+	 * 
+	 * @param name
+	 *            name of the test
+	 */
+	public WSSPolicyTesterAsymm(String name) {
+		super(name);
+	}
+
+	/**
+	 * JUnit suite <p/>
+	 * 
+	 * @return a junit test suite
+	 */
+	public static Test suite() {
+		return new TestSuite(WSSPolicyTesterAsymm.class);
+	}
+
+	/**
+	 * Main method
+	 * 
+	 * @param args
+	 *            command line args
+	 */
+	public static void main(String[] args) {
+		junit.textui.TestRunner.run(suite());
+	}
+
+	/**
+	 * Setup method.
+	 * 
+	 * Initializes an Axis 1 environment to process SOAP messages
+	 * 
+	 * @throws Exception
+	 *             Thrown when there is a problem in setup
+	 */
+	protected void setUp() throws Exception {
+		AxisClient tmpEngine = new AxisClient(new NullProvider());
+		msgContext = new MessageContext(tmpEngine);
+		message = getSOAPMessage();
+	}
+
+	/**
+	 * Constructs a soap envelope.
+	 * 
+	 * @return A SOAP envelope
+	 * @throws Exception
+	 *             if there is any problem constructing the soap envelope
+	 */
+	protected Message getSOAPMessage() throws Exception {
+		InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+		Message msg = new Message(in);
+		msg.setMessageContext(msgContext);
+		return msg;
+	}
+
+	public void testerAsymm() {
+		try {
+			WSSPolicyProcessor processor = new WSSPolicyProcessor();
+			if (!processor.setup()) {
+				return;
+			}
+			String[] files = new String[2];
+			files[0] = "test/policy/SecurityPolicyBindingsAsymmTest.xml";
+			files[1] = "test/policy/SecurityPolicyMsgTest.xml";
+			if (!processor.go(files)) {
+			    System.out.println("Cannot parse the policy files.");
+                System.exit(1);
+            }
+
+			RootPolicyEngineData rootPolicyEngineData = (RootPolicyEngineData) processor.secProcessorContext
+					.popPolicyEngineData();
+			assertNotNull("RootPolicyEngineData missing", rootPolicyEngineData);
+
+			ArrayList peds = rootPolicyEngineData.getTopLevelPEDs();
+			log.debug("Number of top level PolicyEngineData: " + peds.size());
+			WSS4JPolicyData wpd = WSS4JPolicyBuilder.build(peds);
+			createMessageAsymm(wpd);
+
+		} catch (NoSuchMethodException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		} catch (WSSPolicyException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		} catch (Exception e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	private void createMessageAsymm(WSS4JPolicyData wpd) throws Exception {
+		log.info("Before create Message assym....");
+
+		SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+
+		/*
+		 * First get the SOAP envelope as document, then create a security
+		 * header and insert into the document (Envelope)
+		 */
+		Document doc = unsignedEnvelope.getAsDocument();
+		SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
+				.getDocumentElement());
+
+		WSSecHeader secHeader = new WSSecHeader();
+		secHeader.insertSecurityHeader(doc);
+
+		Vector sigParts = new Vector();
+		Vector encPartsInternal = new Vector();
+		Vector encPartsExternal = new Vector();
+
+		/*
+		 * Check is a timestamp is required. If yes create one and add its Id to
+		 * signed parts. According to WSP a timestamp must be signed
+		 */
+		WSSecTimestamp timestamp = null;
+		if (wpd.isIncludeTimestamp()) {
+			timestamp = new WSSecTimestamp();
+			timestamp.prepare(doc);
+			sigParts.add(new WSEncryptionPart(timestamp.getId()));
+		}
+
+		/*
+		 * Check for a recipient token. If one is avaliable use it as token to
+		 * encrypt data to the recipient. This is according to WSP
+		 * specification. Most of the data is extracted from the
+		 * WSS4JPolicyData, only the user info (name/alias of the certificate in
+		 * the keystore) must be provided by some other means.
+		 */
+		WSSecEncrypt recEncrypt = null;
+		WSS4JPolicyToken recToken = null;
+		if ((recToken = wpd.getRecipientToken()) != null) {
+			recEncrypt = new WSSecEncrypt();
+			recEncrypt.setUserInfo("wss4jcert");
+			recEncrypt.setKeyIdentifierType(recToken.getKeyIdentifier());
+			recEncrypt.setSymmetricEncAlgorithm(recToken.getEncAlgorithm());
+			recEncrypt.setKeyEnc(recToken.getEncTransportAlgorithm());
+			recEncrypt.prepare(doc, cryptoSKI);
+		}
+
+		/*
+		 * Check for an initiator token. If one is avaliable use it as token to
+		 * sign data. This is according to WSP specification. Most of the data
+		 * is extracted from the WSS4JPolicyData, only the user info (name/alias
+		 * of the certificate in the keystore) must be provided by some other
+		 * means.
+		 * 
+		 * If SignatureProtection is enabled add the signature to the encrypted
+		 * parts vector. In any case the signature must be in the internal
+		 * ReferenceList (this list is a child of the EncryptedKey element).
+		 * 
+		 * If TokenProtection is enabled add an appropriate signature reference.
+		 * 
+		 * TODO Check / enable for STRTransform
+		 */
+		WSSecSignature iniSignature = null;
+		WSS4JPolicyToken iniToken = null;
+		if ((iniToken = wpd.getInitiatorToken()) != null) {
+			iniSignature = new WSSecSignature();
+			iniSignature.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e",
+					"security");
+			iniSignature.setKeyIdentifierType(iniToken.getKeyIdentifier());
+			iniSignature.setSignatureAlgorithm(iniToken.getSigAlgorithm());
+			iniSignature.prepare(doc, crypto, secHeader);
+			if (wpd.isSignatureProtection()) {
+				encPartsInternal.add(new WSEncryptionPart(iniSignature.getId(),
+						"Element"));
+			}
+			if (wpd.isTokenProtection()) {
+				sigParts.add(new WSEncryptionPart("Token", null, null));
+			}
+		}
+
+		Element body = WSSecurityUtil.findBodyElement(doc, soapConstants);
+		if (body == null) {
+			System.out
+					.println("No SOAP Body found - illegal message structure. Processing terminated");
+			return;
+		}
+		WSEncryptionPart bodyPart = new WSEncryptionPart("Body", soapConstants
+				.getEnvelopeURI(), "Content");
+
+		/*
+		 * Check the protection order. If Encrypt before signing then first take
+		 * all parts and elements to encrypt and encrypt them. Take their ids
+		 * after encryption and put them to the parts to be signed.
+		 * 
+		 */
+		Element externRefList = null;
+		if (Constants.ENCRYPT_BEFORE_SIGNING.equals(wpd.getProtectionOrder())) {
+			/*
+			 * Process Body: it sign and encrypt: first encrypt the body, insert
+			 * the body to the parts to be signed.
+			 * 
+			 * If just to be signed: add the plain Body to the parts to be
+			 * signed
+			 */
+			if (wpd.isSignBody()) {
+				if (wpd.isEncryptBody()) {
+					Vector parts = new Vector();
+					parts.add(bodyPart);
+					externRefList = recEncrypt.encryptForExternalRef(
+							externRefList, parts);
+					sigParts.add(bodyPart);
+				} else {
+					sigParts.add(bodyPart);
+				}
+			}
+			/*
+			 * Here we need to handle signed/encrypted parts:
+			 * 
+			 * Get all parts that need to be encrypted _and_ signed, encrypt
+			 * them, get ids of thier encrypted data elements and add these ids
+			 * to the parts to be signed
+			 * 
+			 * Then encrypt the remaining parts that don't need to be signed.
+			 * 
+			 * Then add the remaining parts that don't nedd to be encrypted to
+			 * the parts to be signed.
+			 * 
+			 * Similar handling for signed/encrypted elements (compare XPath
+			 * strings?)
+			 * 
+			 * After all elements are encrypted put the external refernce list
+			 * to the security header. is at the bottom of the security header)
+			 */
+
+			recEncrypt.addExternalRefElement(externRefList, secHeader);
+
+			/*
+			 * Now handle the supporting tokens - according to OASIS WSP
+			 * supporting tokens are not part of a Binding assertion but a top
+			 * level assertion similar to Wss11 or SignedParts. If supporting
+			 * tokens are available their BST elements have to be added later
+			 * (probably prepended to the initiator token - see below)
+			 */
+
+			/*
+			 * Now add the various elements to the header. We do a strict layout
+			 * here.
+			 * 
+			 */
+			/*
+			 * Prepend Signature to the supporting tokens that sign the primary
+			 * signature
+			 */
+			iniSignature.prependToHeader(secHeader);
+			/*
+			 * This prepends a possible initiator token to the security header
+			 */
+			iniSignature.prependBSTElementToHeader(secHeader);
+			/*
+			 * Here prepend BST elements of supporting tokens
+			 * (EndorsingSupportTokens), then prepend supporting token that do
+			 * not sign the primary signature but are signed by the primary
+			 * signature. Take care of the TokenProtection protery!?
+			 */
+
+			/*
+			 * Add the encrypted key element and then the associated BST element
+			 * recipient token)
+			 */
+			recEncrypt.prependToHeader(secHeader);
+			recEncrypt.prependBSTElementToHeader(secHeader);
+
+			/*
+			 * Now we are ready to per Signature processing.
+			 * 
+			 * First the primary Signature then supporting tokens (Signatures)
+			 * that sign the primary Signature.
+			 */
+			timestamp.prependToHeader(secHeader);
+
+			iniSignature.addReferencesToSign(sigParts, secHeader);
+			iniSignature.computeSignature();
+			Element internRef = recEncrypt.encryptForInternalRef(null,
+					encPartsInternal);
+			recEncrypt.addInternalRefElement(internRef);
+		} else {
+			System.out.println("SignBeforeEncrypt needs to be implemented");
+		}
+
+		log.info("After creating Message asymm....");
+
+		/*
+		 * convert the resulting document into a message first. The
+		 * toSOAPMessage() method performs the necessary c14n call to properly
+		 * set up the signed document and convert it into a SOAP message. Check
+		 * that the contents can't be read (cheching if we can find a specific
+		 * substring). After that we extract it as a document again for further
+		 * processing.
+		 */
+
+		Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(doc);
+		if (log.isDebugEnabled()) {
+			log.debug("Processed message");
+			XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope()
+					.getAsDOM(), new PrintWriter(System.out));
+		}
+		String encryptedString = encryptedMsg.getSOAPPartAsString();
+		assertTrue(encryptedString.indexOf("LogTestService2") == -1 ? true
+		: false);
+		// encryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();
+		verify(doc);
+	}
+
+	/**
+	 * Verifies the soap envelope <p/>
+	 * 
+	 * @param envelope
+	 * @throws Exception
+	 *             Thrown when there is a problem in verification
+	 */
+	private void verify(Document doc) throws Exception {
+		secEngine.processSecurityHeader(doc, null, this, crypto, cryptoSKI);
+		SOAPUtil.updateSOAPMessage(doc, message);
+		String decryptedString = message.getSOAPPartAsString();
+        log.debug(decryptedString);
+		assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true
+				: false);
+	}
+
+	public void handle(Callback[] callbacks) throws IOException,
+			UnsupportedCallbackException {
+		for (int i = 0; i < callbacks.length; i++) {
+			if (callbacks[i] instanceof WSPasswordCallback) {
+				WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+				/*
+				 * here call a function/method to lookup the password for the
+				 * given identifier (e.g. a user name or keystore alias) e.g.:
+				 * pc.setPassword(passStore.getPassword(pc.getIdentfifier)) for
+				 * Testing we supply a fixed name here.
+				 */
+				pc.setPassword("security");
+			} else {
+				throw new UnsupportedCallbackException(callbacks[i],
+						"Unrecognized Callback");
+			}
+		}
+	}
+
+}
diff --git a/test/sandbox/PackageTests.java b/test/sandbox/PackageTests.java
new file mode 100644
index 0000000..aaa4b71
--- /dev/null
+++ b/test/sandbox/PackageTests.java
@@ -0,0 +1,65 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  Licensed under the Apache License, Version 2.0 (the "License");

+ *  you may not use this file except in compliance with the License.

+ *  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ *

+ */

+

+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 sandbox;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+

+/**

+ * Test package for WS-Security tests

+ */

+public class PackageTests extends TestCase {

+

+    public PackageTests(String name) {

+        super(name);

+    }

+

+    public static Test suite() {

+        TestSuite suite = new TestSuite();

+        suite.addTestSuite(TestTrust2.class);

+        return suite;

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+}

diff --git a/test/sandbox/TestTrust2.java b/test/sandbox/TestTrust2.java
new file mode 100644
index 0000000..ea292af
--- /dev/null
+++ b/test/sandbox/TestTrust2.java
@@ -0,0 +1,66 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 sandbox;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.ws.axis.oasis.Scenario1;

+import org.apache.ws.sandbox.security.trust2.samples.SampleSecurityTokenServiceClient;

+

+/**

+ * WS-Trust Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestTrust2 extends TestCase {

+    /**

+     * TestScenario1 constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestTrust2(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestTrust2.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) throws Exception {

+        Scenario1.main(args);

+    }

+

+    public void testScenario1() throws Exception {

+        SampleSecurityTokenServiceClient.main(new String[]{"-lhttp://localhost:8080/axis/services/SampleSecurityTokenService"});

+    }

+}

diff --git a/test/wssec/PackageTests.java b/test/wssec/PackageTests.java
new file mode 100644
index 0000000..f8543bb
--- /dev/null
+++ b/test/wssec/PackageTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test package for WS-Security tests
+ */
+public class PackageTests extends TestCase {
+
+    public PackageTests(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(TestWSSecurityNew.class);
+        suite.addTestSuite(TestWSSecurityNew2.class);
+        suite.addTestSuite(TestWSSecurityNew3.class);
+//        suite.addTestSuite(TestWSSecurity4.class);
+        suite.addTestSuite(TestWSSecurityNew5.class);
+        suite.addTestSuite(TestWSSecurityNew6.class);
+        suite.addTestSuite(TestWSSecurityNew7.class);
+        suite.addTestSuite(TestWSSecurityNew8.class);
+        suite.addTestSuite(TestWSSecurityNew9.class);
+        suite.addTestSuite(TestWSSecurityNew10.class);
+        suite.addTestSuite(TestWSSecurityNew11.class);
+        suite.addTestSuite(TestWSSecurityNew12.class);
+        suite.addTestSuite(TestWSSecurityNew13.class);
+        suite.addTestSuite(TestWSSecurityNew14.class);
+        suite.addTestSuite(TestWSSecurityNewSOAP12.class);
+        // suite.addTestSuite(TestWSSecurityHooks.class);
+        suite.addTestSuite(TestWSSecurityNewST1.class);
+        suite.addTestSuite(TestWSSecurityNewST2.class);
+        suite.addTestSuite(TestWSSecurityNewST3.class);
+        suite.addTestSuite(TestWSSecurityNewDK.class);
+        suite.addTestSuite(TestWSSecurityNewSCT.class);
+        return suite;
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+}
diff --git a/test/wssec/PrivilegedAccessor.java b/test/wssec/PrivilegedAccessor.java
new file mode 100644
index 0000000..bd06f52
--- /dev/null
+++ b/test/wssec/PrivilegedAccessor.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+/*
+ * This class was taken nearly verbatim from http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 
+ * I did add the setValue(Object, String, Object)
+ * Jason Essington <mailto:jasone@greenrivercomputing.com>
+ */
+package wssec;
+import java.lang.reflect.*;
+
+/**
+ * a.k.a. The "ObjectMolester"
+ * <p>
+ * This class is used to access a method or field of an object no
+ * matter what the access modifier of the method or field.  The syntax
+ * for accessing fields and methods is out of the ordinary because this
+ * class uses reflection to peel away protection.
+ * <p>
+ * Here is an example of using this to access a private member.
+ * <code>resolveName</code> is a private method of <code>Class</code>.
+ *
+ * <pre>
+ * Class c = Class.class;
+ * System.out.println(
+ *      PrivilegedAccessor.invokeMethod( c,
+ *                                       "resolveName",
+ *                                       "/net/iss/common/PrivilegeAccessor" ) );
+ * </pre>
+ *
+ * @author Charlie Hubbard (chubbard@iss.net)
+ * @author Prashant Dhokte (pdhokte@iss.net)
+ */
+
+public class PrivilegedAccessor {
+
+    /**
+     * Gets the value of the named field and returns it as an object.
+     *
+     * @param instance the object instance
+     * @param fieldName the name of the field
+     * @return an object representing the value of the field
+     */
+    public static Object getValue( Object instance, String fieldName ) 
+          throws IllegalAccessException, NoSuchFieldException {
+        Field field = getField(instance.getClass(), fieldName);
+        field.setAccessible(true);
+        return field.get(instance);
+    }
+    
+    /**
+     * Sets the value of the given field on the object instance supplied to the value supplied.
+     * @param instance the object instance
+     * @param fieldName the name of the field
+     * @param value the value to assign to the field
+     * @throws IllegalAccessException
+     * @throws NoSuchFieldException
+     */
+    public static void setValue( Object instance, String fieldName, Object value ) 
+          throws IllegalAccessException, NoSuchFieldException {
+       Field field = getField(instance.getClass(), fieldName);
+       field.setAccessible(true);
+       field.set(instance, value);
+    }
+    
+    /**
+     * Calls a method on the given object instance with the given argument.
+     *
+     * @param instance the object instance
+     * @param methodName the name of the method to invoke
+     * @param arg the argument to pass to the method
+     * @see PrivilegedAccessor#invokeMethod(Object,String,Object[])
+     */
+    public static Object invokeMethod( Object instance, String methodName, Object arg ) throws NoSuchMethodException,
+                                                         IllegalAccessException, InvocationTargetException  {
+        Object[] args = new Object[1];
+        args[0] = arg;
+        return invokeMethod(instance, methodName, args);
+    }
+
+    /**
+     * Calls a method on the given object instance with the given arguments.
+     *
+     * @param instance the object instance
+     * @param methodName the name of the method to invoke
+     * @param args an array of objects to pass as arguments
+     * @see PrivilegedAccessor#invokeMethod(Object,String,Object)
+     */
+    public static Object invokeMethod( Object instance, String methodName, Object[] args ) throws NoSuchMethodException,
+                                                             IllegalAccessException, InvocationTargetException  {
+        Class[] classTypes = null;
+        if( args != null) {
+            classTypes = new Class[args.length];
+            for( int i = 0; i < args.length; i++ ) {
+                if( args[i] != null )
+                    classTypes[i] = args[i].getClass();
+            }
+        }
+        return getMethod(instance,methodName,classTypes).invoke(instance,args);
+    }
+
+    /**
+     *
+     * @param instance the object instance
+     * @param methodName the
+     */
+    public static Method getMethod( Object instance, String methodName, Class[] classTypes ) throws NoSuchMethodException {
+        Method accessMethod = getMethod(instance.getClass(), methodName, classTypes);
+        accessMethod.setAccessible(true);
+        return accessMethod;
+    }
+
+    /**
+     * Return the named field from the given class.
+     */
+    private static Field getField(Class thisClass, String fieldName) throws NoSuchFieldException {
+        if (thisClass == null)
+            throw new NoSuchFieldException("Invalid field : " + fieldName);
+        try {
+            return thisClass.getDeclaredField( fieldName );
+        }
+        catch(NoSuchFieldException e) {
+            return getField(thisClass.getSuperclass(), fieldName);
+        }
+    }
+
+    /**
+     * Return the named method with a method signature matching classTypes
+     * from the given class.
+     */
+    private static Method getMethod(Class thisClass, String methodName, Class[] classTypes) throws NoSuchMethodException {
+        if (thisClass == null)
+            throw new NoSuchMethodException("Invalid method : " + methodName);
+        try {
+            return thisClass.getDeclaredMethod( methodName, classTypes );
+        }
+        catch(NoSuchMethodException e) {
+            return getMethod(thisClass.getSuperclass(), methodName, classTypes);
+        }
+    }
+}
diff --git a/test/wssec/SOAPUtil.java b/test/wssec/SOAPUtil.java
new file mode 100644
index 0000000..3dc0190
--- /dev/null
+++ b/test/wssec/SOAPUtil.java
@@ -0,0 +1,46 @@
+package wssec;
+
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.w3c.dom.Document;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.dom.DOMSource;
+import java.io.ByteArrayInputStream;
+
+public class SOAPUtil {
+
+    /**
+     * Convert a DOM Document into a soap message.
+     * <p/>
+     *
+     * @param doc
+     * @return
+     * @throws Exception
+     */
+    public static SOAPMessage toSOAPMessage(Document doc) throws Exception {
+        Canonicalizer c14n =
+                Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
+        byte[] canonicalMessage = c14n.canonicalizeSubtree(doc);
+        ByteArrayInputStream in = new ByteArrayInputStream(canonicalMessage);
+        MessageFactory factory = MessageFactory.newInstance();
+        return factory.createMessage(null, in);
+    }
+
+    /**
+     * Update soap message.
+     * <p/>
+     *
+     * @param doc
+     * @param message
+     * @return
+     * @throws Exception
+     */
+    public static SOAPMessage updateSOAPMessage(Document doc,
+                                                SOAPMessage message)
+            throws Exception {
+        DOMSource domSource = new DOMSource(doc);
+        message.getSOAPPart().setContent(domSource);
+        return message;
+    }
+}
diff --git a/test/wssec/TestBase64.java b/test/wssec/TestBase64.java
new file mode 100644
index 0000000..ac1a0b6
--- /dev/null
+++ b/test/wssec/TestBase64.java
@@ -0,0 +1,121 @@
+/*
+ * Created on 09.09.2005
+ *
+ * To change the template for this generated file go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+package wssec;
+
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.WSSecurityException;
+
+public class TestBase64 extends TestCase {
+
+    private byte[] dataBinary = null;
+    
+    /*
+     * The following String is the value "This is a test\n" encoded
+     * in Base64
+     */
+    private String thisIsATestEnc = "VGhpcyBpcyBhIHRlc3QK";
+    private String thisIsATestClear = "This is a test\n";
+    private String thisIsATestEnc4group = "VGhp\ncyBp\ncyBh\nIHRl\nc3QK";
+    
+    private String encodedBinary;
+    
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(TestBase64.class);
+    }
+
+    public TestBase64(String arg0) {
+        super(arg0);
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        dataBinary = new byte[256];
+        for (int i = 0; i < 256; i++) {
+            dataBinary[i] = (byte)i;
+        }
+    }
+
+    /*
+     * Class under test for String encode(byte[])
+     */
+    public void testEncodebyteArray() {
+        String isATestEnc = Base64.encode(thisIsATestClear.getBytes());
+        assertEquals(isATestEnc, thisIsATestEnc);
+
+        encodedBinary = Base64.encode(dataBinary);
+        byte[] outBinary = null;
+        try {
+            outBinary = Base64.decode(encodedBinary);
+        } catch (WSSecurityException ex) {
+
+        }
+        assertTrue(Arrays.equals(outBinary, dataBinary));
+    }
+
+    /*
+     * Class under test for String encode(byte[], int, boolean)
+     */
+    public void testEncodebyteArrayintboolean() {
+        String isATestEnc = Base64.encode(thisIsATestClear.getBytes(), 4, false);
+        assertEquals(isATestEnc, thisIsATestEnc);
+
+        isATestEnc = Base64.encode(thisIsATestClear.getBytes(), 76, false);
+        assertEquals(isATestEnc, thisIsATestEnc);
+
+        isATestEnc = Base64.encode(thisIsATestClear.getBytes(), 4, true);
+        assertEquals(isATestEnc, thisIsATestEnc4group);
+
+        isATestEnc = Base64.encode(thisIsATestClear.getBytes(), 76, true);
+        assertEquals(isATestEnc, thisIsATestEnc);
+        
+        encodedBinary = Base64.encode(dataBinary, 4, false);
+        byte[] outBinary = null;
+        try {
+            outBinary = Base64.decode(encodedBinary);
+        } catch (WSSecurityException ex) {
+        }
+        assertTrue(Arrays.equals(outBinary, dataBinary));   
+        
+        encodedBinary = Base64.encode(dataBinary, 76, false);
+        outBinary = null;
+        try {
+            outBinary = Base64.decode(encodedBinary);
+        } catch (WSSecurityException ex) {
+        }
+        assertTrue(Arrays.equals(outBinary, dataBinary));        
+        
+        encodedBinary = Base64.encode(dataBinary, 4, true);
+        outBinary = null;
+        try {
+            outBinary = Base64.decode(encodedBinary);
+        } catch (WSSecurityException ex) {
+        }
+        assertTrue(Arrays.equals(outBinary, dataBinary));    
+        
+        encodedBinary = Base64.encode(dataBinary, 76, true);
+        outBinary = null;
+        try {
+            outBinary = Base64.decode(encodedBinary);
+        } catch (WSSecurityException ex) {
+        }
+        assertTrue(Arrays.equals(outBinary, dataBinary));        
+    }
+
+    public void testDecode() {
+        byte[] out = null;
+        byte[] outBinary = null;
+        try {
+            out = Base64.decode(thisIsATestEnc);
+        } catch (WSSecurityException ex) {
+
+        }
+        assertEquals(new String(out), thisIsATestClear);
+    }
+
+}
diff --git a/test/wssec/TestWSSecurity4.java b/test/wssec/TestWSSecurity4.java
new file mode 100644
index 0000000..2b0be85
--- /dev/null
+++ b/test/wssec/TestWSSecurity4.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ * @author Werner Dittmann (Werner.Dittmann@t-online.de)
+ */
+public class TestWSSecurity4 extends TestCase {
+    private static Log log = LogFactory.getLog(TestWSSecurity4.class);
+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+    static final Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");
+
+    MessageContext msgContext;
+    SOAPEnvelope unsignedEnvelope;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurity4(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurity4.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        unsignedEnvelope = getSOAPEnvelope();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws java.lang.Exception if there is any problem constructing the soap envelope
+     */
+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg.getSOAPEnvelope();
+    }
+
+    /**
+     * Test that signs and verifies a WS-Security envelope using SubjectKeyIdentifier.
+     * This test uses the SubjectKeyIdentifier to identify the certificate. It
+     * uses the Direct version, that is it embedds the certificate in the message.
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification
+     */
+//    public void testX509SignatureSKIDirect() throws Exception {
+//        SOAPEnvelope envelope = null;
+//        WSSignEnvelope builder = new WSSignEnvelope();
+//        builder.setUserInfo("wss4jcert", "security");
+//        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER_DIRECT);
+//
+//        // builder.setUserInfo("john", "keypass");
+//        log.info("Before Signing....");
+//        Document doc = unsignedEnvelope.getAsDocument();
+//        Document signedDoc = builder.build(doc, crypto);
+//
+//        /*
+//         * convert the resulting document into a message first. The toSOAPMessage()
+//         * mehtod performs the necessary c14n call to properly set up the signed
+//         * document and convert it into a SOAP message. After that we extract it
+//         * as a document again for further processing.
+//         */
+//
+//        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+//        XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
+//
+//        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+//        log.info("After Signing....");
+//        verify(signedDoc);
+//    }
+
+    /**
+     * Test that signs (twice) and verifies a WS-Security envelope
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification
+     */
+//    public void testDoubleX509SignatureSKIDirect() throws Exception {
+//        SOAPEnvelope envelope = null;
+//        WSSignEnvelope builder = new WSSignEnvelope();
+//        builder.setUserInfo("wss4jcert", "security");
+//        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER_DIRECT);
+//
+//        // builder.setUserInfo("john", "keypass");
+//        Document doc = unsignedEnvelope.getAsDocument();
+//        Document signedDoc = builder.build(doc, crypto);
+//        Document signedDoc1 = builder.build(signedDoc, crypto);
+//        verify(signedDoc1);
+//    }
+
+    /**
+     * Verifies the soap envelope
+     * 
+     * @param env soap envelope
+     * @throws java.lang.Exception Thrown when there is a problem in verification
+     */
+    private void verify(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, null, null, crypto);
+    }
+}
diff --git a/test/wssec/TestWSSecurityHooks.java b/test/wssec/TestWSSecurityHooks.java
new file mode 100644
index 0000000..c83228b
--- /dev/null
+++ b/test/wssec/TestWSSecurityHooks.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.AxisFault;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.axis.security.WSDoAllReceiver;
+import org.apache.ws.axis.security.WSDoAllSender;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.components.crypto.BouncyCastle;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.handler.WSHandlerConstants;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+
+/**
+ * <dl>
+ * <dt><b>Title: </b><dd>WS Security Hooks Test Case</dd>
+ * <p>
+ * <dt><b>Description: </b><dd>Test Case to verify the load...Crypto hooks work properly. 
+ * Also tests the setKeyStore method of Merlin </dd>
+ * </dl>
+ * 
+ * @see org.apache.ws.security.components.crypto.Merlin#setKeyStore
+ * @see org.apache.ws.axis.security.WSDoAllReceiver#loadSignatureCrypto
+ * @see org.apache.ws.axis.security.WSDoAllReceiver#loadDecryptionCrypto
+ * @see org.apache.ws.axis.security.WSDoAllSender#loadSignatureCrypto
+ * @see org.apache.ws.axis.security.WSDoAllSender#loadEncryptionCrypto
+ * 
+ * @author <a href="mailto:jasone@greenrivercomputing.com>Jason Essington</a>
+ * @version $Revision$
+ */
+public class TestWSSecurityHooks extends TestCase implements CallbackHandler
+{
+   private static Log log = LogFactory.getLog(TestWSSecurityHooks.class);
+   private static final String soapMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
+         "<soapenv:Envelope " +
+               "xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" " +
+               "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
+               "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
+            "<soapenv:Header>" +
+            "</soapenv:Header>" +
+            "<soapenv:Body>" +
+               "<ns1:echo " +
+                     "xmlns:ns1=\"http://org.apache.wss4j.wssec/TESTCASE\" " +
+                     "soapenv:encodingStyle=\"http://www.w3.org/2003/05/soap-encoding\">" +
+                  "<inStr xsi:type=\"xsd:string\">ECHO ECHo ECho Echo echo echO ecHO eCHO ECHO</inStr>" +
+               "</ns1:echo>" +
+            "</soapenv:Body>" +
+         "</soapenv:Envelope>";
+
+   KeyStore keystore = null;
+   MessageContext mc = null;
+   
+   public TestWSSecurityHooks(String name) {
+      super(name);
+   }
+   
+   protected void setUp() throws Exception {
+      AxisClient tmpEngine = new AxisClient(new NullProvider());
+      mc = new MessageContext(tmpEngine);
+      mc.setCurrentMessage(getSOAPMessage(soapMessage));
+      mc.setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
+      keystore = loadKeyStore();
+   }
+
+   public static Test suite() {
+      return new TestSuite(TestWSSecurityHooks.class);
+   }
+
+   public static void main(String[] args) {
+      junit.textui.TestRunner.run(suite());
+   }
+   
+   //
+   //
+   // Tests
+   //
+   //
+   
+   public void testCryptoHook() throws Exception {
+      assertNotNull("", keystore);
+      Crypto crypto = new TestCryptoImpl(keystore);
+      assertNotNull(PrivilegedAccessor.getValue(crypto, "keystore"));
+   }
+   public void testSenderLoadSignatureHook() throws Exception {
+      TestSenderImpl sender = new TestSenderImpl();
+      // we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
+      PrivilegedAccessor.setValue(sender, "msgContext", mc);
+      PrivilegedAccessor.invokeMethod(sender, "decodeSignatureParameter", new Object[] {});
+      assertNotNull(PrivilegedAccessor.getValue(sender, "sigCrypto"));
+   }
+   public void testSenderLoadEncryptionHook() throws Exception {
+      TestSenderImpl sender = new TestSenderImpl();
+      // decodeEcnryptionParameter() is rather insistant on having a user (anyUser)
+      sender.setOption(WSHandlerConstants.ENCRYPTION_USER, "anyUserWillDo");
+      // we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
+      PrivilegedAccessor.setValue(sender, "msgContext", mc);
+      PrivilegedAccessor.invokeMethod(sender, "decodeEncryptionParameter", new Object[] {});
+      assertNotNull(PrivilegedAccessor.getValue(sender, "encCrypto"));
+   }
+   public void testReceiverLoadSignatureHook() throws Exception {
+      TestReceiverImpl receiver = new TestReceiverImpl();
+      PrivilegedAccessor.invokeMethod(receiver, "decodeSignatureParameter", new Object[] {});
+      assertNotNull(PrivilegedAccessor.getValue(receiver, "sigCrypto"));
+   }
+   public void testReceiverLoadDecryptionHook() throws Exception {
+      TestReceiverImpl receiver = new TestReceiverImpl();
+      PrivilegedAccessor.invokeMethod(receiver, "decodeDecryptionParameter", new Object[] {});
+      assertNotNull(PrivilegedAccessor.getValue(receiver, "decCrypto"));
+   }
+   
+   public void testRoundTripWithHooks() throws Exception {
+      // Setup our sender to Encrypt and Sign a soap message
+      TestSenderImpl sender = new TestSenderImpl();
+      sender.setOption(WSHandlerConstants.ACTOR, "test");
+      sender.setOption(WSHandlerConstants.USER, "16c73ab6-b892-458f-abf5-2f875f74882e");
+      sender.setOption(WSHandlerConstants.ACTION, "Encrypt Signature");
+      sender.setOption(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
+      sender.setOption(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
+      sender.invoke(mc);
+      
+      // Make sure that at least SOMETHING happened
+      String soapPart = mc.getCurrentMessage().getSOAPPartAsString();
+      assertNotSame("The message has not been Encrypted or Signed", soapPart, soapMessage);
+      
+      // Prepare the message context for the response
+      Message message = getSOAPMessage(soapPart);
+      mc.setPastPivot(true);
+      mc.setCurrentMessage(message);
+      
+      // Setup our receiver for the decryption / signature validation
+      TestReceiverImpl receiver = new TestReceiverImpl();
+      receiver.setOption(WSHandlerConstants.ACTOR, "test");
+      receiver.setOption(WSHandlerConstants.ACTION, "Encrypt Signature");
+      receiver.invoke(mc);
+   }
+   
+   //
+   //
+   // Test Utility Classes
+   //
+   //
+      
+   /**
+    * This is a subclass of Merlin that uses the setKeyStore() method rather than the 
+    * load(is) method to set the private keystore field.
+    */
+   public class TestCryptoImpl extends BouncyCastle {
+      TestCryptoImpl(KeyStore ks) throws Exception {
+         super(null);
+         assertNotNull(ks);
+         setKeyStore(ks);
+      }
+   }
+   
+   /**
+    * Subclass of WSDoAllReceiver that creates the Crypto's directly
+    */
+   public class TestReceiverImpl extends WSDoAllReceiver
+   {
+      protected Crypto loadDecryptionCrypto() throws AxisFault {
+         try {
+            return new TestCryptoImpl(keystore);
+         } catch(Exception e) {
+            fail("Failed to create a Crypto instance.");
+            throw new AxisFault("Failed to create a Crypto instance.", e);
+         }
+      }
+      protected Crypto loadSignatureCrypto() throws AxisFault {
+         try {
+            return new TestCryptoImpl(keystore);
+         } catch(Exception e) {
+            fail("Failed to create a Crypto instance.");
+            throw new AxisFault("Failed to create a Crypto instance.", e);
+         }
+      }
+   }
+   
+   /**
+    * Subclass of WSDoAllSender that creates the Crypto's directly
+    */
+   public class TestSenderImpl extends WSDoAllSender
+   {
+      protected Crypto loadEncryptionCrypto() throws AxisFault {
+         try {
+            return new TestCryptoImpl(keystore);
+         } catch(Exception e) {
+            fail("Failed to create a Crypto instance.");
+            throw new AxisFault("Failed to create a Crypto instance.", e);
+         }
+      }
+      protected Crypto loadSignatureCrypto() throws AxisFault {
+         try {
+            return new TestCryptoImpl(keystore);
+         } catch(Exception e) {
+            fail("Failed to create a Crypto instance.");
+            throw new AxisFault("Failed to create a Crypto instance.", e);
+         }
+      }
+   }
+   
+   
+   //
+   //
+   // test utility methods
+   //
+   //
+   
+   protected Message getSOAPMessage(String message) throws Exception {
+      InputStream in = new ByteArrayInputStream(message.getBytes());
+      Message msg = new Message(in);
+      msg.setMessageContext(mc);
+      return msg;
+   }
+   
+   protected KeyStore loadKeyStore() throws Exception {
+      KeyStore ks = null;
+      FileInputStream is = null;
+      is = new FileInputStream("keys/x509.PFX.MSFT");
+      ks = KeyStore.getInstance("pkcs12");
+      String password = "security";
+      ks.load(is, password.toCharArray());
+      return ks;
+   }
+   
+   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+      for (int i = 0; i < callbacks.length; i++) {
+         if (callbacks[i] instanceof WSPasswordCallback) {
+            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+            pc.setPassword("security");
+            
+         } else {
+            throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+         }
+      }
+   }
+   
+}
diff --git a/test/wssec/TestWSSecurityNew.java b/test/wssec/TestWSSecurityNew.java
new file mode 100644
index 0000000..4acf0fe
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecHeader;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestWSSecurityNew extends TestCase {
+    private static Log log = LogFactory.getLog(TestWSSecurityNew.class);
+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+    static final Crypto crypto = CryptoFactory.getInstance();
+
+    MessageContext msgContext;
+    SOAPEnvelope unsignedEnvelope;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityNew(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityNew.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        unsignedEnvelope = getSOAPEnvelope();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws java.lang.Exception if there is any problem constructing the soap envelope
+     */
+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg.getSOAPEnvelope();
+    }
+
+    /**
+     * Test that signs and verifies a WS-Security envelope.
+     * The test uses the ThumbprintSHA1 key identifier type. 
+     * 
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification
+     */
+    public void testX509SignatureIS() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        log.info("Before Signing IS....");
+        Document doc = unsignedEnvelope.getAsDocument();
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        /*
+         * convert the resulting document into a message first. The toSOAPMessage()
+         * mehtod performs the necessary c14n call to properly set up the signed
+         * document and convert it into a SOAP message. After that we extract it
+         * as a document again for further processing.
+         */
+
+        if (log.isDebugEnabled()) {
+            log.debug("Signed message with IssuerSerial key identifier:");
+            XMLUtils.PrettyElementToWriter(signedDoc.getDocumentElement(), new PrintWriter(System.out));
+        }
+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+        if (log.isDebugEnabled()) {
+            log.debug("Signed message with IssuerSerial key identifier(1):");
+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
+        }
+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+        log.info("After Signing IS....");
+        verify(signedDoc);
+    }
+
+
+    /**
+     * Test that signs (twice) and verifies a WS-Security envelope.
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification
+     */
+    public void testDoubleX509SignatureIS() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        Document doc = unsignedEnvelope.getAsDocument();
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+        Document signedDoc1 = builder.build(signedDoc, crypto, secHeader);
+        verify(signedDoc1);
+    }
+
+    /**
+     * Verifies the soap envelope.
+     * This method verfies all the signature generated. 
+     * 
+     * @param env soap envelope
+     * @throws java.lang.Exception Thrown when there is a problem in verification
+     */
+    private void verify(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, null, null, crypto);
+    }
+}
diff --git a/test/wssec/TestWSSecurityNew10.java b/test/wssec/TestWSSecurityNew10.java
new file mode 100644
index 0000000..4257e04
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew10.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecEncrypt;
+import org.apache.ws.security.message.WSSecUsernameToken;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.token.Reference;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+/**
+ * TestCase10 for testing HMAC_SHA1 in wss4j. Based on TestCase9.
+ * 
+ * The objective of this TestCase is to test the HMAC_SHA1 signature.
+ * 
+ * @author Dimuthu Leelarathne. (muthulee@yahoo.com)
+ */
+public class TestWSSecurityNew10 extends TestCase implements CallbackHandler {
+    private static Log log = LogFactory.getLog(TestWSSecurityNew10.class);
+
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+            + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+            + "   <soapenv:Body>"
+            + "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test10/LogTestService10\"></ns1:testMethod>"
+            + "   </soapenv:Body>" + "</soapenv:Envelope>";
+
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    static final Crypto crypto = CryptoFactory.getInstance();
+
+    MessageContext msgContext;
+
+    Message message;
+
+    private byte[] sharedSecret = "SriLankaSriLankaSriLanka".getBytes();
+
+    /**
+     * TestWSSecurity constructor <p/>
+     * 
+     * @param name
+     *            name of the test
+     */
+    public TestWSSecurityNew10(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityNew10.class);
+    }
+
+    /**
+     * Main method <p/>
+     * 
+     * @param args
+     *            command line args
+     */
+    // public static void main(String[] args) {
+    // junit.textui.TestRunner.run(suite());
+    // }
+    /**
+     * Setup method <p/>
+     * 
+     * @throws Exception
+     *             Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        message = getSOAPMessage();
+    }
+
+    /**
+     * Constructs a soap envelope <p/>
+     * 
+     * @return soap envelope
+     * @throws Exception
+     *             if there is any problem constructing the soap envelope
+     */
+    protected Message getSOAPMessage() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg;
+    }
+
+    /**
+     * Test that encrypts and signs a WS-Security envelope, then performs
+     * verification and decryption. <p/>
+     * 
+     * @throws Exception
+     *             Thrown when there is any problem in signing, encryption,
+     *             decryption, or verification
+     */
+    public void testEMBED_SECURITY_TOKEN_REF() throws Exception {
+
+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+        SOAPEnvelope envelope = null;
+        WSSecEncrypt wsEncrypt = new WSSecEncrypt();
+
+        // Get the message as document
+        log.info("Before Encryption....");
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+
+        /*
+         * Step 1 :: Add a UserNameToken. Step 2 :: Add an Id to it. Step 3 ::
+         * Create a Reference to the UserNameToken. Step 4 :: Setting necessary
+         * parameters in WSEncryptBody. Step 5 :: Encrypt using the using the
+         * password of UserNameToken.
+         */
+
+        // Step 1
+        String username = "Dimthu";
+        String password = "Sri Lanka Sri Lanka UOM ";
+        byte[] key = password.getBytes();
+
+        WSSecUsernameToken builder = new WSSecUsernameToken();
+        builder.setPasswordType(WSConstants.PASSWORD_TEXT);
+        builder.setUserInfo(username, password);
+        builder.build(doc, secHeader);
+
+        // Step 3 ::
+        Reference ref = new Reference(doc);
+        ref.setURI("#" + builder.getId());
+        ref.setValueType("UsernameToken");
+        SecurityTokenReference secRef = new SecurityTokenReference(doc);
+        secRef.setReference(ref);
+
+        // adding the namespace
+        WSSecurityUtil.setNamespace(secRef.getElement(), WSConstants.WSSE_NS,
+                WSConstants.WSSE_PREFIX);
+
+        // Step 4 ::
+        wsEncrypt.setKeyIdentifierType(WSConstants.EMBED_SECURITY_TOKEN_REF);
+        wsEncrypt.setSecurityTokenReference(secRef);
+        wsEncrypt.setKey(key);
+        wsEncrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+
+        // Step 4 :: Encrypting using the key.
+        Document encDoc = wsEncrypt.build(doc, crypto, secHeader);
+
+        /*
+         * convert the resulting document into a message first. The
+         * toSOAPMessage() mehtod performs the necessary c14n call to properly
+         * set up the signed document and convert it into a SOAP message. After
+         * that we extract it as a document again for further processing.
+         */
+
+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(encDoc);
+
+        if (log.isDebugEnabled()) {
+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope()
+                    .getAsDOM(), new PrintWriter(System.out));
+        }
+        log.info("Encryption Done\n");
+        // verifyEMBED_SECURITY_TOKEN_REF(signedMsg.getSOAPEnvelope().getAsDocument());
+    }
+
+    /**
+     * Verifies the soap envelope <p/>
+     * 
+     * @param doc
+     * @throws Exception
+     *             Thrown when there is a problem in verification
+     */
+    private void verifyEMBED_SECURITY_TOKEN_REF(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, "", this, null);
+        log.info("Success ......");
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
+     */
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
+                    pc.setPassword("Sri Lanka Sri Lanka UOM ");
+                } else if (pc.getUsage() == WSPasswordCallback.DECRYPT) {
+                    pc.setKey("Sri Lanka Sri Lanka UOM ".getBytes());
+
+                }
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i],
+                        "Unrecognized Callback");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+}
diff --git a/test/wssec/TestWSSecurityNew11.java b/test/wssec/TestWSSecurityNew11.java
new file mode 100644
index 0000000..36a7baf
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew11.java
@@ -0,0 +1,409 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import java.io.ByteArrayInputStream;

+import java.io.InputStream;

+import java.io.PrintWriter;

+import java.util.Vector;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew11 extends TestCase {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew11.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");

+

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew11(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew11.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * This test uses the direct reference key identifier (certificate included

+     * as a BinarySecurityToken (BST) in the message). The test signs the message

+     * body (SOAP Body) and uses the STRTransform to sign the embedded certificate

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509SignatureDirectSTR() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcert", "security");

+        // builder.setUserInfo("john", "keypass");

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope.getAsDOM());

+        Vector parts = new Vector();

+        

+        /*

+         * Set up to sign body and use STRTransorm to sign

+         * the signature token (e.g. X.509 certificate)

+         */

+        WSEncryptionPart encP =

+            new WSEncryptionPart(

+                soapConstants.getBodyQName().getLocalPart(),

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+        encP =

+            new WSEncryptionPart(

+                "STRTransform",

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+

+        builder.setParts(parts);

+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);

+

+        log.info("Before Signing STR DirectReference....");

+        Document doc = unsignedEnvelope.getAsDocument();

+

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with STR DirectReference key identifier:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing STR DirectReference....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * This test uses the IssuerSerialDirect reference key identifier (certificate included

+     * as a BinarySecurityToken (BST) in the message) but identified with IssuerSerialNumber

+     * and <b>not</b> with a Reference (relative URI). The test signs the message

+     * body (SOAP Body) and uses the STRTransform to sign the embedded certificate

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+//    public void testX509SignatureISDirectSTR() throws Exception {

+//        SOAPEnvelope envelope = null;

+//        WSSignEnvelope builder = new WSSignEnvelope();

+//        builder.setUserInfo("wss4jcert", "security");

+//        // builder.setUserInfo("john", "keypass");

+//        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope);

+//        Vector parts = new Vector();

+//        

+//        /*

+//         * Set up to sign body and use STRTransorm to sign

+//         * the signature token (e.g. X.509 certificate)

+//         */

+//        WSEncryptionPart encP =

+//            new WSEncryptionPart(

+//                soapConstants.getBodyQName().getLocalPart(),    // define the body

+//                soapConstants.getEnvelopeURI(),

+//                "Content");

+//        parts.add(encP);

+//        encP =

+//            new WSEncryptionPart(

+//                "STRTransform",                // reserved word to use STRTransform

+//                soapConstants.getEnvelopeURI(),

+//                "Content");

+//        parts.add(encP);

+//

+//        builder.setParts(parts);

+//        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL_DIRECT);

+//

+//        log.info("Before Signing STR ISDirect....");

+//        Document doc = unsignedEnvelope.getAsDocument();

+//        Document signedDoc = builder.build(doc, crypto);

+//

+//        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+//        if (log.isDebugEnabled()) {

+//            log.debug("Signed message with STR IssuerSerialDirect key identifier:");

+//            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+//        }

+//        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+//        log.info("After Signing STR ISDirect....");

+//        verify(signedDoc);

+//    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * This test uses the IssuerSerial reference key identifier (certificate not included

+     * in the message)and reads the certificate from a keystore using IssuerSerialNumber

+     * to identify it.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    

+

+    public void testX509SignatureISSTR() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcert", "security");

+        // builder.setUserInfo("john", "keypass");

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope.getAsDOM());

+        Vector parts = new Vector();

+        

+        /*

+         * Set up to sign body and use STRTransorm to sign

+         * the signature token (e.g. X.509 certificate)

+         */

+        WSEncryptionPart encP =

+            new WSEncryptionPart(

+                soapConstants.getBodyQName().getLocalPart(),    // define the body

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+        encP =

+            new WSEncryptionPart(

+                "STRTransform",                // reserved word to use STRTransform

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+

+        builder.setParts(parts);

+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);

+

+        log.info("Before Signing STR IS....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with STR IssuerSerial key identifier:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing STR IS....");

+        verify(signedDoc);

+    }

+    

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * This test uses the SubjectKeyIdentifier key identifier (certificate not included

+     * in the message) and reads the certificate from a keystore using SKI

+     * to identify it.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    

+

+    public void testX509SignatureSKISTR() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcert", "security");

+        // builder.setUserInfo("john", "keypass");

+        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope.getAsDOM());

+        Vector parts = new Vector();

+        

+        /*

+         * Set up to sign body and use STRTransorm to sign

+         * the signature token (e.g. X.509 certificate)

+         */

+        WSEncryptionPart encP =

+            new WSEncryptionPart(

+                soapConstants.getBodyQName().getLocalPart(),    // define the body

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+        encP =

+            new WSEncryptionPart(

+                "STRTransform",                // reserved word to use STRTransform

+                soapConstants.getEnvelopeURI(),

+                "Content");

+        parts.add(encP);

+

+        builder.setParts(parts);

+        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);

+

+        log.info("Before Signing STR SKI....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with STR SKI key identifier:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing STR SKI....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * This test uses the SubjectKeyIdentifierDirect key identifier (certificate included

+     * in the message).

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    

+

+//    public void testX509SignatureSKIDirectSTR() throws Exception {

+//        SOAPEnvelope envelope = null;

+//        WSSignEnvelope builder = new WSSignEnvelope();

+//        builder.setUserInfo("wss4jcert", "security");

+//        // builder.setUserInfo("john", "keypass");

+//        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope);

+//        Vector parts = new Vector();

+//        

+//        /*

+//         * Set up to sign body and use STRTransorm to sign

+//         * the signature token (e.g. X.509 certificate)

+//         */

+//        WSEncryptionPart encP =

+//            new WSEncryptionPart(

+//                soapConstants.getBodyQName().getLocalPart(),    // define the body

+//                soapConstants.getEnvelopeURI(),

+//                "Content");

+//        parts.add(encP);

+//        encP =

+//            new WSEncryptionPart(

+//                "STRTransform",                // reserved word to use STRTransform

+//                soapConstants.getEnvelopeURI(),

+//                "Content");

+//        parts.add(encP);

+//

+//        builder.setParts(parts);

+//        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER_DIRECT);

+//

+//        log.info("Before Signing STR SKIDirect....");

+//        Document doc = unsignedEnvelope.getAsDocument();

+//        Document signedDoc = builder.build(doc, crypto);

+//

+//        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+//        if (log.isDebugEnabled()) {

+//            log.debug("Signed message with STR SKIDirect key identifier:");

+//            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+//        }

+//        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+//        log.info("After Signing STR SKIDirect....");

+//        verify(signedDoc);

+//    }

+

+

+    /**

+     * Verifies the soap envelope

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, null, crypto);

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew12.java b/test/wssec/TestWSSecurityNew12.java
new file mode 100644
index 0000000..6f2c114
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew12.java
@@ -0,0 +1,253 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import org.apache.xml.security.signature.XMLSignature;

+

+import java.io.ByteArrayInputStream;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ * @author Werner Dittmann (Werner.Dittmann@siemens.com)

+ */

+public class TestWSSecurityNew12 extends TestCase {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew12.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");

+

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew12(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew12.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope using SubjectKeyIdentifier.

+     * This test uses the SubjectKeyIdentifier to identify the certificate. It

+     * uses the Direct version, that is it embedds the certificate in the message.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509SignatureDSA_SKI() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcertDSA", "security");

+        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);

+        builder.setSignatureAlgorithm(XMLSignature.ALGO_ID_SIGNATURE_DSA);

+        

+        // builder.setUserInfo("john", "keypass");

+        log.info("Before SigningDSA_SKIDirect....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with DSA_SKI key identifier:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After SigningDSA_SKIDirect....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope using SubjectKeyIdentifier.

+     * This test uses the SubjectKeyIdentifier to identify the certificate. 

+     * It gets a certificate with a DSA public key algo to sign, WSSignEnvelope shall

+     * detect the algo and set the signature algo accordingly.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509SignatureDSA_Autodetect() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcertDSA", "security");

+        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);

+        

+        // builder.setUserInfo("john", "keypass");

+        log.info("Before SigningDSA_Autodetect....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with DSA_Autodetect:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After SigningDSA_Autodetect....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope using SubjectKeyIdentifier.

+     * This test uses the SubjectKeyIdentifier to identify the certificate. 

+     * It gets a certificate with a RSA public key algo to sign, WSSignEnvelope shall

+     * detect the algo and set the signature algo accordingly.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509SignatureRSA_Autodetect() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("wss4jcert", "security");

+        builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);

+        

+        // builder.setUserInfo("john", "keypass");

+        log.info("Before SigningRSA_Autodetect....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with RSA Autodetect:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After SigningRSA_Autodetect....");

+        verify(signedDoc);

+    }

+    

+    /**

+     * Verifies the soap envelope

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, null, crypto);

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew13.java b/test/wssec/TestWSSecurityNew13.java
new file mode 100644
index 0000000..96bf028
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew13.java
@@ -0,0 +1,190 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.message.WSSecUsernameToken;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+

+import org.apache.xml.security.signature.XMLSignature;

+

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Werner Dittmann (Wern.erDittmann@siemens.com)

+ */

+public class TestWSSecurityNew13 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew13.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew13(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew13.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+ 

+    /**

+     * Test the specific signing mehtod that use UsernameToken values

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testUsernameTokenSigning() throws Exception {

+        SOAPEnvelope envelope = null;

+        Document doc = unsignedEnvelope.getAsDocument();

+

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        WSSecUsernameToken builder = new WSSecUsernameToken();

+        builder.setPasswordType(WSConstants.PASSWORD_TEXT);

+        builder.setUserInfo("wernerd", "verySecret");

+        builder.addCreated();

+        builder.addNonce();

+        builder.prepare(doc);

+        

+        WSSecSignature sign = new WSSecSignature();

+        sign.setUsernameToken(builder);

+        sign.setKeyIdentifierType(WSConstants.UT_SIGNING);

+        sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

+        log.info("Before signing....");

+        sign.build(doc, null, secHeader);

+        log.info("Before adding UsernameToken PW Text....");

+        builder.prependToHeader(secHeader);

+        Document signedDoc = doc;

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Message with UserNameToken PW Text:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After adding UsernameToken PW Text....");

+        verify(signedDoc);

+    }

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        log.info("Before verifying UsernameToken....");

+        secEngine.processSecurityHeader(doc, null, this, null);

+        log.info("After verifying UsernameToken....");

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("verySecret");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew14.java b/test/wssec/TestWSSecurityNew14.java
new file mode 100644
index 0000000..f4d840d
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew14.java
@@ -0,0 +1,187 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import java.io.ByteArrayInputStream;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew14 extends TestCase {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew14.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance();

+

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew14(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew14.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope.

+     * The test uses the ThumbprintSHA1 key identifier type. 

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509SignatureThumb() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+        // builder.setUserInfo("john", "keypass");

+        log.info("Before Signing ThumbprintSHA1....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message with ThumbprintSHA1 key identifier:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing ThumbprintSHA1....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs (twice) and verifies a WS-Security envelope.

+     * The test uses the ThumbprintSHA1 key identifier type.

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testDoubleX509SignatureThumb() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        // builder.setUserInfo("john", "keypass");

+        builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);        

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+        Document signedDoc1 = builder.build(signedDoc, crypto, secHeader);

+        verify(signedDoc1);

+    }

+

+    /**

+     * Verifies the soap envelope.

+     * This method verfies all the signature generated. 

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, null, crypto);

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew15.java b/test/wssec/TestWSSecurityNew15.java
new file mode 100644
index 0000000..7c1478d
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew15.java
@@ -0,0 +1,258 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.SOAPConstants;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecHeader;

+import org.apache.ws.security.util.WSSecurityUtil;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+import java.util.Vector;

+

+/**

+ * Test that encrypt and decrypt a WS-Security envelope.

+ * 

+ * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric key.

+ * The test case creates a ReferenceList element that references EncryptedData

+ * elements. The ReferencesList element is put into the Security header, not

+ * as child of the EncryptedKey. The EncryptedData elements contain a KeyInfo

+ * that references the EncryptedKey via a STR/Reference structure.

+ * 

+ * <p/>

+ * 

+ * Refer to OASIS WS Security spec 1.1, chap 7.7

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ * @author Werner Dittmann (werner@apache.org)

+ */

+public class TestWSSecurityNew15 extends TestCase implements CallbackHandler {

+	private static Log log = LogFactory.getLog(TestWSSecurityNew15.class);

+

+	static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"

+			+ "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"

+			+ "   <soapenv:Body>"

+			+ "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>"

+			+ "   </soapenv:Body>" + "</soapenv:Envelope>";

+

+	static final WSSecurityEngine secEngine = new WSSecurityEngine();

+

+	static final Crypto crypto = CryptoFactory

+			.getInstance("cryptoSKI.properties");

+

+	MessageContext msgContext;

+

+	Message message;

+

+	/**

+	 * TestWSSecurity constructor <p/>

+	 * 

+	 * @param name

+	 *            name of the test

+	 */

+	public TestWSSecurityNew15(String name) {

+		super(name);

+	}

+

+	/**

+	 * JUnit suite <p/>

+	 * 

+	 * @return a junit test suite

+	 */

+	public static Test suite() {

+		return new TestSuite(TestWSSecurityNew15.class);

+	}

+

+	/**

+	 * Main method <p/>

+	 * 

+	 * @param args

+	 *            command line args

+	 */

+	public static void main(String[] args) {

+		junit.textui.TestRunner.run(suite());

+	}

+

+	/**

+	 * Setup method <p/>

+	 * 

+	 * @throws Exception

+	 *             Thrown when there is a problem in setup

+	 */

+	protected void setUp() throws Exception {

+		AxisClient tmpEngine = new AxisClient(new NullProvider());

+		msgContext = new MessageContext(tmpEngine);

+		message = getSOAPMessage();

+	}

+

+	/**

+	 * Constructs a soap envelope <p/>

+	 * 

+	 * @return soap envelope

+	 * @throws Exception

+	 *             if there is any problem constructing the soap envelope

+	 */

+	protected Message getSOAPMessage() throws Exception {

+		InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+		Message msg = new Message(in);

+		msg.setMessageContext(msgContext);

+		return msg;

+	}

+

+	/**

+	 * Test that encrypt and decrypt a WS-Security envelope.

+	 * 

+	 * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric

+	 * key.

+	 * 

+	 * @throws Exception

+	 *             Thrown when there is any problem in signing or verification

+	 */

+	public void testEncryptionDecryptionRSA15() throws Exception {

+		SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+		SOAPEnvelope envelope = null;

+		WSSecEncrypt builder = new WSSecEncrypt();

+		builder.setUserInfo("wss4jcert");

+		builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);

+		builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);

+		Document doc = unsignedEnvelope.getAsDocument();

+		WSSecHeader secHeader = new WSSecHeader();

+		secHeader.insertSecurityHeader(doc);

+		log.info("Before Encryption Triple DES....");

+

+		/*

+		 * Prepare the Encrypt object with the token, setup data structure

+		 */

+		builder.prepare(doc, crypto);

+

+		/*

+		 * Set up the parts structure to encrypt the body

+		 */

+		SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc

+				.getDocumentElement());

+		Vector parts = new Vector();

+		WSEncryptionPart encP = new WSEncryptionPart(soapConstants

+				.getBodyQName().getLocalPart(), soapConstants.getEnvelopeURI(),

+				"Content");

+		parts.add(encP);

+

+		/*

+		 * Encrypt the parts (Body), create EncrypedData elements that reference

+		 * the EncryptedKey, and get a ReferenceList that can be put into the

+		 * Security header. Be sure that the ReferenceList is after the

+		 * EncryptedKey element in the Security header (strict layout)

+		 */

+		Element refs = builder.encryptForExternalRef(null, parts);

+		builder.addExternalRefElement(refs, secHeader);

+

+		/*

+		 * now add (prepend) the EncryptedKey element, then a

+		 * BinarySecurityToken if one was setup during prepare

+		 */

+		builder.prependToHeader(secHeader);

+

+		builder.prependBSTElementToHeader(secHeader);

+

+		Document encryptedDoc = doc;

+		log.info("After Encryption Triple DES....");

+

+		/*

+		 * convert the resulting document into a message first. The

+		 * toSOAPMessage() method performs the necessary c14n call to properly

+		 * set up the signed document and convert it into a SOAP message. Check

+		 * that the contents can't be read (checking if we can find a specific

+		 * substring). After that we extract it as a document again for further

+		 * processing.

+		 */

+

+		Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+		if (log.isDebugEnabled()) {

+			log.debug("Encrypted message, RSA-15 keytransport, 3DES:");

+			XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope()

+					.getAsDOM(), new PrintWriter(System.out));

+		}

+		String encryptedString = encryptedMsg.getSOAPPartAsString();

+		assertTrue(encryptedString.indexOf("LogTestService2") == -1 ? true

+				: false);

+		encryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();

+		verify(encryptedDoc);

+	}

+

+	/**

+	 * Verifies the soap envelope <p/>

+	 * 

+	 * @param envelope

+	 * @throws Exception

+	 *             Thrown when there is a problem in verification

+	 */

+	private void verify(Document doc) throws Exception {

+		secEngine.processSecurityHeader(doc, null, this, crypto);

+		SOAPUtil.updateSOAPMessage(doc, message);

+		String decryptedString = message.getSOAPPartAsString();

+		if (log.isDebugEnabled()) {

+			System.out.println("\n" + decryptedString + "\n");

+		}

+		assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true

+				: false);

+	}

+

+	public void handle(Callback[] callbacks) throws IOException,

+			UnsupportedCallbackException {

+		for (int i = 0; i < callbacks.length; i++) {

+			if (callbacks[i] instanceof WSPasswordCallback) {

+				WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+				/*

+				 * here call a function/method to lookup the password for the

+				 * given identifier (e.g. a user name or keystore alias) e.g.:

+				 * pc.setPassword(passStore.getPassword(pc.getIdentfifier)) for

+				 * Testing we supply a fixed name here.

+				 */

+				pc.setPassword("security");

+			} else {

+				throw new UnsupportedCallbackException(callbacks[i],

+						"Unrecognized Callback");

+			}

+		}

+	}

+}

diff --git a/test/wssec/TestWSSecurityNew2.java b/test/wssec/TestWSSecurityNew2.java
new file mode 100644
index 0000000..b58f632
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew2.java
@@ -0,0 +1,264 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSEncryptionPart;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+import java.util.Vector;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew2 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew2.class);

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +

+            "   <soapenv:Body>" +

+            "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>" +

+            "   </soapenv:Body>" +

+            "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");

+    MessageContext msgContext;

+    Message message;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew2(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew2.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that encrypt and decrypt a WS-Security envelope.

+     * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric

+     * key.

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is any problem in signing or verification

+     */

+    public void testEncryptionDecryptionRSA15() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        WSSecEncrypt builder = new WSSecEncrypt();

+        builder.setUserInfo("wss4jcert");

+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);

+        builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+        log.info("Before Encryption Triple DES....");

+        Document encryptedDoc = builder.build(doc, crypto, secHeader);

+        log.info("After Encryption Triple DES....");

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * method performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. Check that the contents can't

+          * be read (cheching if we can find a specific substring). After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message, RSA-15 keytransport, 3DES:");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        String encryptedString = encryptedMsg.getSOAPPartAsString();

+        assertTrue(encryptedString.indexOf("LogTestService2") == -1 ? true : false);

+        encryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();

+        verify(encryptedDoc);

+

+        /*

+         * second run, same Junit set up, but change encryption method, 

+         * key identification, encryption mode (Element now), and data to encrypt.

+         * This tests if several runs of different algorithms on same builder/cipher 

+         * setup are ok.

+         */

+        message = getSOAPMessage(); // create fresh message envrionment

+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);

+        builder.setSymmetricEncAlgorithm(WSConstants.AES_128);

+        Vector parts = new Vector();

+        WSEncryptionPart encP =

+            new WSEncryptionPart("testMethod", "uri:LogTestService2", "Element");

+        parts.add(encP);

+        builder.setParts(parts);

+        unsignedEnvelope = message.getSOAPEnvelope();

+        doc = unsignedEnvelope.getAsDocument();

+        secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);        

+        log.info("Before Encryption AES 128/RSA-15....");

+        encryptedDoc = builder.build(doc, crypto, secHeader);

+        log.info("After Encryption AES 128/RSA-15....");

+        encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message, RSA-15 keytransport, AES 128:");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        encryptedString = encryptedMsg.getSOAPPartAsString();

+        assertTrue(encryptedString.indexOf("LogTestService2") == -1 ? true : false);

+        encryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();

+        verify(encryptedDoc);

+    }

+

+    /**

+     * Test that encrypt and decrypt a WS-Security envelope.

+     * This test uses the RSA OAEP alogrithm to transport (wrap) the symmetric

+     * key.

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is any problem in signing or verification

+     */

+     public void testEncryptionDecryptionOAEP() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        WSSecEncrypt builder = new WSSecEncrypt();

+        builder.setUserInfo("wss4jcert");

+        builder.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);

+        builder.setKeyEnc(WSConstants.KEYTRANSPORT_RSAOEP);

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);        

+        log.info("Before Encryption Triple DES/RSA-OAEP....");

+        Document encryptedDoc = builder.build(doc, crypto, secHeader);

+        log.info("After Encryption Triple DES/RSA-OAEP....");

+

+        Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message, RSA-OAEP keytransport, 3DES:");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        String encryptedString = encryptedMsg.getSOAPPartAsString();

+        assertTrue(encryptedString.indexOf("LogTestService2") == -1 ? true : false);

+        encryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();

+        verify(encryptedDoc);

+

+    }

+    

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param envelope 

+     * @throws Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        String decryptedString = message.getSOAPPartAsString();

+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true : false);

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew3.java b/test/wssec/TestWSSecurityNew3.java
new file mode 100644
index 0000000..3627cb2
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew3.java
@@ -0,0 +1,187 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew3 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew3.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance();

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew3(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew3.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509Signature() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        log.info("Before Signing....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+        Document signedDoc = builder.build(doc, CryptoFactory.getInstance(), secHeader);

+

+         /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs (twice) and verifies a WS-Security envelope

+     * <p>

+     * @throws  java.lang.Exception  Thrown when there is any problem in signing or verification

+     public void testDoubleX509Signature() throws Exception {

+     SOAPEnvelope envelope = null;

+     WSSignEnvelope builder = new WSSignEnvelope();

+     Document doc = unsignedEnvelope.getAsDocument();

+     Document signedDoc = builder.build(doc);

+     signedDoc =  builder.build(signedDoc);

+     verify(signedDoc);

+     }

+     */

+

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("password");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew5.java b/test/wssec/TestWSSecurityNew5.java
new file mode 100644
index 0000000..c956014
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew5.java
@@ -0,0 +1,205 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.message.WSSecUsernameToken;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew5 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew5.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew5(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew5.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that adds a UserNameToken with password Digest to a WS-Security envelope

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testUsernameTokenDigest() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecUsernameToken builder = new WSSecUsernameToken();

+        builder.setUserInfo("wernerd", "verySecret");

+        log.info("Before adding UsernameToken PW Digest....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+        Document signedDoc = builder.build(doc, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * method performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Message with UserNameToken PW Digest:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After adding UsernameToken PW Digest....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that adds a UserNameToken with password text to a WS-Security envelope

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testUsernameTokenText() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecUsernameToken builder = new WSSecUsernameToken();

+        builder.setPasswordType(WSConstants.PASSWORD_TEXT);

+        builder.setUserInfo("wernerd", "verySecret");

+        log.info("Before adding UsernameToken PW Text....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+        Document signedDoc = builder.build(doc, secHeader);

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Message with UserNameToken PW Text:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After adding UsernameToken PW Text....");

+        verify(signedDoc);

+    }

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        log.info("Before verifying UsernameToken....");

+        secEngine.processSecurityHeader(doc, null, this, null);

+        log.info("After verifying UsernameToken....");

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("verySecret");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew6.java b/test/wssec/TestWSSecurityNew6.java
new file mode 100644
index 0000000..066a708
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew6.java
@@ -0,0 +1,204 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.SOAPPart;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+/**

+ * WS-Security Test Case <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew6 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew6.class);

+

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"

+            + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"

+            + "   <soapenv:Body>"

+            + "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService6\"></ns1:testMethod>"

+            + "   </soapenv:Body>" + "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+

+    static final Crypto crypto = CryptoFactory.getInstance();

+

+    MessageContext msgContext;

+

+    Message message;

+

+    /**

+     * TestWSSecurity constructor <p/>

+     * 

+     * @param name

+     *            name of the test

+     */

+    public TestWSSecurityNew6(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew6.class);

+    }

+

+    /**

+     * Main method <p/>

+     * 

+     * @param args

+     *            command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method <p/>

+     * 

+     * @throws Exception

+     *             Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception

+     *             if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that encrypts and signs a WS-Security envelope, then performs

+     * verification and decryption <p/>

+     * 

+     * @throws Exception

+     *             Thrown when there is any problem in signing, encryption,

+     *             decryption, or verification

+     */

+    public void testEncryptionSigning() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        WSSecEncrypt encrypt = new WSSecEncrypt();

+        WSSecSignature sign = new WSSecSignature();

+        encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");

+        sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        log.info("Before Encryption....");

+        Document doc = unsignedEnvelope.getAsDocument();

+

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document encryptedDoc = encrypt.build(doc, crypto, secHeader);

+        Document encryptedSignedDoc = sign.build(encryptedDoc, crypto,

+                secHeader);

+        /*

+         * convert the resulting document into a message first. The

+         * toSOAPMessage() mehtod performs the necessary c14n call to properly

+         * set up the signed document and convert it into a SOAP message. After

+         * that we extract it as a document again for further processing.

+         */

+

+        Message encryptedMsg = (Message) SOAPUtil

+                .toSOAPMessage(encryptedSignedDoc);

+        String s = encryptedMsg.getSOAPPartAsString();

+        ((SOAPPart) message.getSOAPPart()).setCurrentMessage(s,

+                SOAPPart.FORM_STRING);

+

+        Document encryptedSignedDoc1 = message.getSOAPEnvelope()

+                .getAsDocument();

+        log.info("After Encryption....");

+        verify(encryptedSignedDoc1);

+    }

+

+    /**

+     * Verifies the soap envelope <p/>

+     * 

+     * @param envelope

+     * @throws Exception

+     *             Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        if (log.isDebugEnabled()) {

+            XMLUtils.PrettyElementToWriter(

+                    message.getSOAPEnvelope().getAsDOM(), new PrintWriter(

+                            System.out));

+        }

+    }

+

+    public void handle(Callback[] callbacks) throws IOException,

+            UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for the

+                 * given identifier (e.g. a user name or keystore alias) e.g.:

+                 * pc.setPassword(passStore.getPassword(pc.getIdentfifier)) for

+                 * Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i],

+                        "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew7.java b/test/wssec/TestWSSecurityNew7.java
new file mode 100644
index 0000000..ae88a50
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew7.java
@@ -0,0 +1,195 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+/**

+ * WS-Security Test Case <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew7 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew7.class);

+

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"

+            + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"

+            + "   <soapenv:Body>"

+            + "      <ns1:testMethod xmlns:ns1=\"urn:LogTestService7\"></ns1:testMethod>"

+            + "   </soapenv:Body>" + "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+

+    static final Crypto crypto = CryptoFactory.getInstance();

+

+    MessageContext msgContext;

+

+    Message message;

+

+    /**

+     * TestWSSecurity constructor <p/>

+     * 

+     * @param name

+     *            name of the test

+     */

+    public TestWSSecurityNew7(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew7.class);

+    }

+

+    /**

+     * Main method <p/>

+     * 

+     * @param args

+     *            command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method <p/>

+     * 

+     * @throws Exception

+     *             Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception

+     *             if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that encrypt and then again encrypts (Super encryption) WS-Security

+     * envelope and then verifies ist <p/>

+     * 

+     * @throws Exception

+     *             Thrown when there is any problem in encryption or

+     *             verification

+     */

+    public void testEncryptionEncryption() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        WSSecEncrypt encrypt = new WSSecEncrypt();

+        encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");

+        log.info("Before Encryption....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        Document encryptedDoc = encrypt.build(doc, crypto, secHeader);

+        Document encryptedEncryptedDoc = encrypt.build(encryptedDoc, crypto,

+                secHeader);

+

+        /*

+         * convert the resulting document into a message first. The

+         * toSOAPMessage() mehtod performs the necessary c14n call to properly

+         * set up the signed document and convert it into a SOAP message. After

+         * that we extract it as a document again for further processing.

+         */

+

+        Message encryptedMsg = (Message) SOAPUtil

+                .toSOAPMessage(encryptedEncryptedDoc);

+        encryptedEncryptedDoc = encryptedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Encryption....");

+        verify(encryptedEncryptedDoc);

+    }

+

+    /**

+     * Verifies the soap envelope <p/>

+     * 

+     * @param envelope

+     * @throws Exception

+     *             Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        if (log.isDebugEnabled()) {

+            XMLUtils.PrettyElementToWriter(

+                    message.getSOAPEnvelope().getAsDOM(), new PrintWriter(

+                            System.out));

+        }

+    }

+

+    public void handle(Callback[] callbacks) throws IOException,

+            UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for the

+                 * given identifier (e.g. a user name or keystore alias) e.g.:

+                 * pc.setPassword(passStore.getPassword(pc.getIdentfifier)) for

+                 * Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i],

+                        "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew8.java b/test/wssec/TestWSSecurityNew8.java
new file mode 100644
index 0000000..9ad47d6
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew8.java
@@ -0,0 +1,210 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.SOAPPart;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew8 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew8.class);

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +

+            "   <soapenv:Body>" +

+            "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\"></ns1:testMethod>" +

+            "   </soapenv:Body>" +

+            "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance();

+    MessageContext msgContext;

+    Message message;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew8(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew8.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that first signs, then encrypts a WS-Security envelope.

+     * The test uses the IssuerSerial key identifier to get the keys for

+     * signature and encryption. Encryption uses 3DES.

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is any problem in signing, encryption,

+     *                   decryption, or verification

+     */

+    public void testSigningEncryptionIS3DES() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        

+        WSSecEncrypt encrypt = new WSSecEncrypt();

+        encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");

+        encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);

+        encrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);

+

+        WSSecSignature sign = new WSSecSignature();

+        sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);

+

+        log.info("Before Sign/Encryption....");

+        Document doc = unsignedEnvelope.getAsDocument();

+

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+        

+        Document signedDoc = sign.build(doc, crypto, secHeader);

+        Document encryptedSignedDoc = encrypt.build(signedDoc, crypto, secHeader);

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * method performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedSignedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed and encrypted message with IssuerSerial key identifier (both), 3DES:");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        

+        String s = encryptedMsg.getSOAPPartAsString();

+        ((SOAPPart)message.getSOAPPart()).setCurrentMessage(s, SOAPPart.FORM_STRING);

+                

+        Document encryptedSignedDoc1 = message.getSOAPEnvelope().getAsDocument();

+        log.info("After Sign/Encryption....");

+        verify(encryptedSignedDoc1);

+    }

+

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param doc 

+     * @throws Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        if (log.isDebugEnabled()) {

+            log.debug("Verfied and decrypted message:");

+            XMLUtils.PrettyElementToWriter(message.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNew9.java b/test/wssec/TestWSSecurityNew9.java
new file mode 100644
index 0000000..2fae7de
--- /dev/null
+++ b/test/wssec/TestWSSecurityNew9.java
@@ -0,0 +1,228 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.SOAPPart;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecEncrypt;

+import org.apache.ws.security.message.WSSecHeader;

+import org.apache.ws.security.message.WSSecSignature;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+// import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNew9 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNew9.class);

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +

+            "   <soapenv:Body>" +

+            "      <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test9/LogTestService9\"></ns1:testMethod>" +

+            "   </soapenv:Body>" +

+            "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance();

+    MessageContext msgContext;

+    Message message;

+

+    private static final byte[] key = {

+        (byte)0x31, (byte)0xfd,

+        (byte)0xcb, (byte)0xda,

+        (byte)0xfb, (byte)0xcd,

+        (byte)0x6b, (byte)0xa8,

+        (byte)0xe6, (byte)0x19,

+        (byte)0xa7, (byte)0xbf,

+        (byte)0x51, (byte)0xf7,

+        (byte)0xc7, (byte)0x3e,

+        (byte)0x80, (byte)0xae,

+        (byte)0x98, (byte)0x51,

+        (byte)0xc8, (byte)0x51,

+        (byte)0x34, (byte)0x04,

+    };

+

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNew9(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNew9.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that encrypts and signs a WS-Security envelope, then performs

+     * verification and decryption.

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is any problem in signing, encryption,

+     *                   decryption, or verification

+     */

+    public void testSigningEncryptionEmbedded() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        WSSecEncrypt encrypt = new WSSecEncrypt();

+        WSSecSignature sign = new WSSecSignature();

+        

+        encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");

+        encrypt.setKeyIdentifierType(WSConstants.EMBEDDED_KEYNAME);

+        encrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);        

+        encrypt.setKey(key);

+

+        sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        log.info("Before Encryption....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);                

+        Document signedDoc = sign.build(doc, crypto, secHeader);

+        Document encryptedSignedDoc = encrypt.build(signedDoc, crypto, secHeader);

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedSignedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message, RSA-OAEP keytransport, 3DES:");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        String s = encryptedMsg.getSOAPPartAsString();

+        ((SOAPPart)message.getSOAPPart()).setCurrentMessage(s, SOAPPart.FORM_STRING);

+                

+        Document encryptedSignedDoc1 = message.getSOAPEnvelope().getAsDocument();

+        log.info("After Encryption....");

+        verify(encryptedSignedDoc1);

+    }

+

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param doc 

+     * @throws Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+    }

+    

+    /* (non-Javadoc)

+     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])

+     */

+    public void handle(Callback[] callbacks)

+        throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {

+                    pc.setKey(key);

+                }

+                else {

+                    pc.setPassword("security");

+                }

+            } else {

+                throw new UnsupportedCallbackException(

+                    callbacks[i],

+                    "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNewDK.java b/test/wssec/TestWSSecurityNewDK.java
new file mode 100644
index 0000000..687a759
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewDK.java
@@ -0,0 +1,370 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSConstants;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecDKEncrypt;

+import org.apache.ws.security.message.WSSecDKSign;

+import org.apache.ws.security.message.WSSecEncryptedKey;

+import org.apache.ws.security.message.WSSecHeader;

+import org.apache.xml.security.signature.XMLSignature;

+import org.w3c.dom.Document;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+

+public class TestWSSecurityNewDK extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNewDK.class);

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +

+            "   <soapenv:Body>" +

+            "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>" +

+            "   </soapenv:Body>" +

+            "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");

+    MessageContext msgContext;

+    Message message;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNewDK(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNewDK.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test encryption using a DerivedKeyToken using TRIPLEDES

+     * @throws Exception Thrown when there is any problem in signing or 

+     * verification

+     */

+    public void testEncryptionDecryptionTRIPLEDES() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        //EncryptedKey

+        WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();

+        encrKeyBuilder.setUserInfo("wss4jcert");

+        encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+        encrKeyBuilder.prepare(doc, crypto);

+

+        //Key information from the EncryptedKey

+        byte[] ek = encrKeyBuilder.getEphemeralKey();

+        String tokenIdentifier = encrKeyBuilder.getId();  

+        

+        //Derived key encryption

+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();

+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);

+        encrBuilder.setExternalKey(ek, tokenIdentifier);

+        Document encryptedDoc = encrBuilder.build(doc, crypto, secHeader);

+        

+        encrKeyBuilder.prependToHeader(secHeader);

+        encrKeyBuilder.prependBSTElementToHeader(secHeader);

+

+        

+       Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+       if (log.isDebugEnabled()) {

+           log.debug("Encrypted message: 3DES  + DerivedKeys");

+           XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope()

+                    .getAsDOM(), new PrintWriter(System.out));

+       }

+//       String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);

+//       System.out.println(out);

+       verify(doc);

+    }

+

+    /**

+     * Test encryption using a DerivedKeyToken using AES128 

+     * @throws Exception Thrown when there is any problem in signing or verification

+     */

+     public void testEncryptionDecryptionAES128() throws Exception {

+         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+         Document doc = unsignedEnvelope.getAsDocument();

+         WSSecHeader secHeader = new WSSecHeader();

+         secHeader.insertSecurityHeader(doc);

+

+         //EncryptedKey

+         WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();

+         encrKeyBuilder.setUserInfo("wss4jcert");

+         encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+         encrKeyBuilder.prepare(doc, crypto);

+

+         //Key information from the EncryptedKey

+         byte[] ek = encrKeyBuilder.getEphemeralKey();

+         String tokenIdentifier = encrKeyBuilder.getId();  

+         

+         //Derived key encryption

+         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();

+         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);

+         encrBuilder.setExternalKey(ek, tokenIdentifier);

+         Document encryptedDoc = encrBuilder.build(doc, crypto, secHeader);

+         

+         encrKeyBuilder.prependToHeader(secHeader);

+         encrKeyBuilder.prependBSTElementToHeader(secHeader);

+         

+        Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message: 3DES  + DerivedKeys");

+            XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope()

+                    .getAsDOM(), new PrintWriter(System.out));

+        }

+//        String out = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);

+//        System.out.println(out);

+        verify(doc);

+     }

+     

+     public void testSignature() throws Exception {

+         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+         Document doc = unsignedEnvelope.getAsDocument();

+         WSSecHeader secHeader = new WSSecHeader();

+         secHeader.insertSecurityHeader(doc);

+

+         //EncryptedKey

+         WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();

+         encrKeyBuilder.setUserInfo("wss4jcert");

+         encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+         encrKeyBuilder.prepare(doc, crypto);

+

+         //Key information from the EncryptedKey

+         byte[] ek = encrKeyBuilder.getEphemeralKey();

+         String tokenIdentifier = encrKeyBuilder.getId();         

+         

+         //Derived key encryption

+         WSSecDKSign sigBuilder = new WSSecDKSign();

+         sigBuilder.setExternalKey(ek, tokenIdentifier);

+         sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

+         Document signedDoc = sigBuilder.build(doc, crypto, secHeader);

+         

+         encrKeyBuilder.prependToHeader(secHeader);

+         encrKeyBuilder.prependBSTElementToHeader(secHeader);

+         

+         Message signedMessage = (Message) SOAPUtil.toSOAPMessage(doc);

+         if (log.isDebugEnabled()) {

+             log.debug("Encrypted message: 3DES  + DerivedKeys");

+             XMLUtils.PrettyElementToWriter(signedMessage.getSOAPEnvelope()

+                    .getAsDOM(), new PrintWriter(System.out));

+         }

+//         String out = org.apache.ws.security.util.XMLUtils

+//                .PrettyDocumentToString(signedDoc);

+//        System.out.println(out);

+         verify(doc);

+     }

+     

+     public void testSignatureEncrypt() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        Document doc = unsignedEnvelope.getAsDocument();

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);

+

+        //EncryptedKey

+        WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();

+        encrKeyBuilder.setUserInfo("wss4jcert");

+        encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+        encrKeyBuilder.prepare(doc, crypto);

+

+        //Key information from the EncryptedKey

+        byte[] ek = encrKeyBuilder.getEphemeralKey();

+        String tokenIdentifier = encrKeyBuilder.getId();

+

+        //Derived key encryption

+        WSSecDKSign sigBuilder = new WSSecDKSign();

+        sigBuilder.setExternalKey(ek, tokenIdentifier);

+        sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

+        log.info("Before HMAC-SHA1 signature");

+        Document signedDoc = sigBuilder.build(doc, crypto, secHeader);

+

+        //Derived key signature

+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();

+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);

+        encrBuilder.setExternalKey(ek, tokenIdentifier);

+        Document signedEncryptedDoc = encrBuilder.build(signedDoc, crypto,

+                secHeader);

+

+        encrKeyBuilder.prependToHeader(secHeader);

+        encrKeyBuilder.prependBSTElementToHeader(secHeader);

+

+        Message signedMessage = (Message) SOAPUtil

+                .toSOAPMessage(signedEncryptedDoc);

+

+        if (log.isDebugEnabled()) {

+            log.debug("Encrypted message: 3DES  + DerivedKeys");

+            XMLUtils.PrettyElementToWriter(signedMessage.getSOAPEnvelope()

+                    .getAsDOM(), new PrintWriter(System.out));

+        }

+//        String out = org.apache.ws.security.util.XMLUtils

+//                .PrettyDocumentToString(signedEncryptedDoc);

+//        System.out.println(out);

+        verify(signedEncryptedDoc);

+    }

+     

+     public void testEncryptSignature() throws Exception {

+         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+         Document doc = unsignedEnvelope.getAsDocument();

+         WSSecHeader secHeader = new WSSecHeader();

+         secHeader.insertSecurityHeader(doc);

+

+         //EncryptedKey

+         WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();

+         encrKeyBuilder.setUserInfo("wss4jcert");

+         encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);

+         encrKeyBuilder.prepare(doc, crypto);

+         

+         //Key information from the EncryptedKey

+         byte[] ek = encrKeyBuilder.getEphemeralKey();

+         String tokenIdentifier = encrKeyBuilder.getId();

+         

+         //Derived key encryption

+         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();

+         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);

+         encrBuilder.setExternalKey(ek, tokenIdentifier);

+         encrBuilder.build(doc, crypto, secHeader);

+         

+         //Derived key signature

+         WSSecDKSign sigBuilder = new WSSecDKSign();

+         sigBuilder.setExternalKey(ek, tokenIdentifier);

+         sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);

+         log.info("Before HMAC-SHA1 signature");

+         Document encryptedSignedDoc = sigBuilder.build(doc, crypto,

+                secHeader);

+         

+         encrKeyBuilder.prependToHeader(secHeader);

+         encrKeyBuilder.prependBSTElementToHeader(secHeader);

+         

+         Message signedMessage = (Message) SOAPUtil

+                .toSOAPMessage(encryptedSignedDoc);

+         

+         if (log.isDebugEnabled()) {

+            log.debug("Encrypted message: 3DES  + DerivedKeys");

+            XMLUtils.PrettyElementToWriter(signedMessage.getSOAPEnvelope()

+                    .getAsDOM(), new PrintWriter(System.out));

+        }

+        

+//         String out = org.apache.ws.security.util.XMLUtils

+//                .PrettyDocumentToString(encryptedSignedDoc);

+//         System.out.println(out);

+         verify(encryptedSignedDoc);

+     }

+    

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param envelope 

+     * @throws Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, crypto);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        String decryptedString = message.getSOAPPartAsString();

+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true : false);

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i],

+                        "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNewSCT.java b/test/wssec/TestWSSecurityNewSCT.java
new file mode 100644
index 0000000..387b075
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewSCT.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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 wssec;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.SecureRandom;
+import java.util.Hashtable;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import junit.framework.TestCase;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.conversation.ConversationConstants;
+import org.apache.ws.security.message.WSSecDKEncrypt;
+import org.apache.ws.security.message.WSSecDKSign;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSecurityContextToken;
+import org.apache.xml.security.signature.XMLSignature;
+import org.w3c.dom.Document;
+
+/**
+ * Testcase to test WSSecSecurityContextToken
+ * 
+ * @see org.apache.ws.security.message.WSSecSecurityContextToken
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class TestWSSecurityNewSCT extends TestCase implements CallbackHandler {
+
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+            + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+            + "   <soapenv:Body>"
+            + "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>"
+            + "   </soapenv:Body>" + "</soapenv:Envelope>";
+
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    static final Crypto crypto = CryptoFactory
+            .getInstance("cryptoSKI.properties");
+
+    MessageContext msgContext;
+
+    Message message;
+
+    /**
+     * Table of secrets idexd by the sct identifiers
+     */
+    private Hashtable secrets = new Hashtable();
+
+    /**
+     * @param arg0
+     */
+    public TestWSSecurityNewSCT(String arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Setup method <p/>
+     * 
+     * @throws Exception
+     *             Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        message = getSOAPMessage();
+    }
+
+    public void testBuild() {
+        try {
+            SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+            Document doc = unsignedEnvelope.getAsDocument();
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+
+            WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken();
+            sctBuilder.prepare(doc, crypto);
+            
+            sctBuilder.prependSCTElementToHeader(doc, secHeader);
+
+            String out = org.apache.ws.security.util.XMLUtils
+                    .PrettyDocumentToString(doc);
+
+            assertTrue(
+                    "SecurityContextToken missing",
+                    out
+                            .indexOf(ConversationConstants.SECURITY_CONTEXT_TOKEN_LN) > 0);
+            assertTrue("wsc:Identifier missing", out
+                    .indexOf(ConversationConstants.IDENTIFIER_LN) > 0);
+
+            // System.out.println(out);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Test encryption using a derived key which is based on a secret associated
+     * with a security context token
+     */
+    public void testSCTDKTEncrypt() {
+        try {
+            SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+            Document doc = unsignedEnvelope.getAsDocument();
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+
+            WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken();
+            sctBuilder.prepare(doc, crypto);
+
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] tempSecret = new byte[16];
+            random.nextBytes(tempSecret);
+
+            // Store the secret
+            this.secrets.put(sctBuilder.getIdentifier(), tempSecret);
+
+            String tokenId = sctBuilder.getSctId();
+
+            // Derived key encryption
+            WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+            encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+            encrBuilder.setExternalKey(tempSecret, tokenId);
+            encrBuilder.build(doc, crypto, secHeader);
+
+            sctBuilder.prependSCTElementToHeader(doc, secHeader);
+
+            // String out = org.apache.ws.security.util.XMLUtils
+            //          .PrettyDocumentToString(doc);
+            // System.out.println(out);
+
+            verify(doc);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    public void testSCTKDKTSign() {
+        try {
+            SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+            Document doc = unsignedEnvelope.getAsDocument();
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+
+            WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken();
+            sctBuilder.prepare(doc, crypto);
+
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] tempSecret = new byte[16];
+            random.nextBytes(tempSecret);
+
+            // Store the secret
+            this.secrets.put(sctBuilder.getIdentifier(), tempSecret);
+
+            String tokenId = sctBuilder.getSctId();
+
+            // Derived key signature
+            WSSecDKSign sigBuilder = new WSSecDKSign();
+            sigBuilder.setExternalKey(tempSecret, tokenId);
+            sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
+            sigBuilder.build(doc, crypto, secHeader);
+            
+            sctBuilder.prependSCTElementToHeader(doc, secHeader);
+
+//            String out = org.apache.ws.security.util.XMLUtils
+//                     .PrettyDocumentToString(doc);
+//            System.out.println(out);
+
+            verify(doc);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+    
+    public void testSCTKDKTSignEncrypt() {
+        try {
+            SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+            Document doc = unsignedEnvelope.getAsDocument();
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+
+            WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken();
+            sctBuilder.prepare(doc, crypto);
+
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] tempSecret = new byte[16];
+            random.nextBytes(tempSecret);
+
+            // Store the secret
+            this.secrets.put(sctBuilder.getIdentifier(), tempSecret);
+
+            String tokenId = sctBuilder.getSctId();
+
+            // Derived key signature
+            WSSecDKSign sigBuilder = new WSSecDKSign();
+            sigBuilder.setExternalKey(tempSecret, tokenId);
+            sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
+            sigBuilder.build(doc, crypto, secHeader);
+
+            // Derived key encryption
+            WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+            encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+            encrBuilder.setExternalKey(tempSecret, tokenId);
+            encrBuilder.build(doc, crypto, secHeader);
+
+            sctBuilder.prependSCTElementToHeader(doc, secHeader);
+
+//            String out = org.apache.ws.security.util.XMLUtils
+//                     .PrettyDocumentToString(doc);
+
+//            System.out.println(out);
+
+            verify(doc);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    public void testSCTKDKTEncryptSign() {
+        try {
+            SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+            Document doc = unsignedEnvelope.getAsDocument();
+            WSSecHeader secHeader = new WSSecHeader();
+            secHeader.insertSecurityHeader(doc);
+
+            WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken();
+            sctBuilder.prepare(doc, crypto);
+
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            byte[] tempSecret = new byte[16];
+            random.nextBytes(tempSecret);
+
+            // Store the secret
+            this.secrets.put(sctBuilder.getIdentifier(), tempSecret);
+
+            String tokenId = sctBuilder.getSctId();
+
+            // Derived key encryption
+            WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+            encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+            encrBuilder.setExternalKey(tempSecret, tokenId);
+            encrBuilder.build(doc, crypto, secHeader);
+
+            // Derived key signature
+            WSSecDKSign sigBuilder = new WSSecDKSign();
+            sigBuilder.setExternalKey(tempSecret, tokenId);
+            sigBuilder.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
+            sigBuilder.build(doc, crypto, secHeader);
+
+            sctBuilder.prependSCTElementToHeader(doc, secHeader);
+
+//            String out = org.apache.ws.security.util.XMLUtils
+//                     .PrettyDocumentToString(doc);
+//            System.out.println(out);
+
+            verify(doc);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+    
+    /**
+     * Verifies the soap envelope <p/>
+     * 
+     * @param envelope
+     * @throws Exception
+     *             Thrown when there is a problem in verification
+     */
+    private void verify(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, null, this, crypto);
+        SOAPUtil.updateSOAPMessage(doc, message);
+        String decryptedString = message.getSOAPPartAsString();
+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true
+                : false);
+    }
+
+    /**
+     * Constructs a soap envelope <p/>
+     * 
+     * @return soap envelope
+     * @throws Exception
+     *             if there is any problem constructing the soap envelope
+     */
+    protected Message getSOAPMessage() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg;
+    }
+
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                byte[] secret = (byte[]) this.secrets.get(pc.getIdentifer());
+                pc.setKey(secret);
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i],
+                        "Unrecognized Callback");
+            }
+        }
+    }
+
+}
diff --git a/test/wssec/TestWSSecurityNewSOAP12.java b/test/wssec/TestWSSecurityNewSOAP12.java
new file mode 100644
index 0000000..4bf396d
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewSOAP12.java
@@ -0,0 +1,181 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.components.crypto.Crypto;

+import org.apache.ws.security.components.crypto.CryptoFactory;

+import org.apache.ws.security.message.WSSecSignature;

+import org.apache.ws.security.message.WSSecHeader;

+import org.w3c.dom.Document;

+

+import java.io.ByteArrayInputStream;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNewSOAP12 extends TestCase {

+    private static Log log = LogFactory.getLog(TestWSSecurityNewSOAP12.class);

+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<SOAP-ENV:Body>" + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">" + "<value xmlns=\"\">15</value>" + "</add>" + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+    static final Crypto crypto = CryptoFactory.getInstance();

+

+    MessageContext msgContext;

+    SOAPEnvelope unsignedEnvelope;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNewSOAP12(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNewSOAP12.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        unsignedEnvelope = getSOAPEnvelope();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws java.lang.Exception if there is any problem constructing the soap envelope

+     */

+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg.getSOAPEnvelope();

+    }

+

+    /**

+     * Test that signs and verifies a WS-Security envelope

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testX509Signature() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        // builder.setUserInfo("john", "keypass");

+        log.info("Before Signing....");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);                

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * mehtod performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Signed message SOAP 1.2:");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        log.info("After Signing....");

+        verify(signedDoc);

+    }

+

+    /**

+     * Test that signs (twice) and verifies a WS-Security envelope

+     * <p/>

+     * 

+     * @throws java.lang.Exception Thrown when there is any problem in signing or verification

+     */

+    public void testDoubleX509Signature() throws Exception {

+        SOAPEnvelope envelope = null;

+        WSSecSignature builder = new WSSecSignature();

+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");

+        // builder.setUserInfo("john", "keypass");

+        Document doc = unsignedEnvelope.getAsDocument();

+        

+        WSSecHeader secHeader = new WSSecHeader();

+        secHeader.insertSecurityHeader(doc);                

+

+        Document signedDoc = builder.build(doc, crypto, secHeader);

+        Document signedDoc1 = builder.build(signedDoc, crypto, secHeader);

+        verify(signedDoc1);

+    }

+

+    /**

+     * Verifies the soap envelope

+     * 

+     * @param env soap envelope

+     * @throws java.lang.Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, null, crypto);

+    }

+}

diff --git a/test/wssec/TestWSSecurityNewST1.java b/test/wssec/TestWSSecurityNewST1.java
new file mode 100644
index 0000000..9da03c1
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewST1.java
@@ -0,0 +1,201 @@
+/*

+ * Copyright  2003-2004 The Apache Software Foundation.

+ *

+ *  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 wssec;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestSuite;

+

+import org.apache.ws.security.saml.SAMLIssuerFactory;

+import org.apache.ws.security.saml.SAMLIssuer;

+import org.apache.ws.security.saml.SAMLIssuerFactory;

+

+import org.apache.axis.Message;

+import org.apache.axis.MessageContext;

+import org.apache.axis.client.AxisClient;

+import org.apache.axis.utils.XMLUtils;

+import org.apache.axis.configuration.NullProvider;

+import org.apache.axis.message.SOAPEnvelope;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.ws.security.WSPasswordCallback;

+import org.apache.ws.security.WSSecurityEngine;

+import org.apache.ws.security.message.WSSAddSAMLToken;

+import org.w3c.dom.Document;

+

+import org.opensaml.SAMLAssertion;

+

+import javax.security.auth.callback.Callback;

+import javax.security.auth.callback.CallbackHandler;

+import javax.security.auth.callback.UnsupportedCallbackException;

+import java.io.ByteArrayInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.PrintWriter;

+

+/**

+ * WS-Security Test Case

+ * <p/>

+ * 

+ * @author Davanum Srinivas (dims@yahoo.com)

+ */

+public class TestWSSecurityNewST1 extends TestCase implements CallbackHandler {

+    private static Log log = LogFactory.getLog(TestWSSecurityNewST1.class);

+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +

+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +

+            "   <soapenv:Body>" +

+            "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>" +

+            "   </soapenv:Body>" +

+            "</soapenv:Envelope>";

+

+    static final WSSecurityEngine secEngine = new WSSecurityEngine();

+

+    // static final Crypto crypto = CryptoFactory.getInstance("crypto.properties");

+    MessageContext msgContext;

+    Message message;

+

+    /**

+     * TestWSSecurity constructor

+     * <p/>

+     * 

+     * @param name name of the test

+     */

+    public TestWSSecurityNewST1(String name) {

+        super(name);

+    }

+

+    /**

+     * JUnit suite

+     * <p/>

+     * 

+     * @return a junit test suite

+     */

+    public static Test suite() {

+        return new TestSuite(TestWSSecurityNewST1.class);

+    }

+

+    /**

+     * Main method

+     * <p/>

+     * 

+     * @param args command line args

+     */

+    public static void main(String[] args) {

+        junit.textui.TestRunner.run(suite());

+    }

+

+    /**

+     * Setup method

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is a problem in setup

+     */

+    protected void setUp() throws Exception {

+        AxisClient tmpEngine = new AxisClient(new NullProvider());

+        msgContext = new MessageContext(tmpEngine);

+        message = getSOAPMessage();

+    }

+

+    /**

+     * Constructs a soap envelope

+     * <p/>

+     * 

+     * @return soap envelope

+     * @throws Exception if there is any problem constructing the soap envelope

+     */

+    protected Message getSOAPMessage() throws Exception {

+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());

+        Message msg = new Message(in);

+        msg.setMessageContext(msgContext);

+        return msg;

+    }

+

+    /**

+     * Test that encrypt and decrypt a WS-Security envelope.

+     * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric

+     * key.

+     * <p/>

+     * 

+     * @throws Exception Thrown when there is any problem in signing or verification

+     */

+    public void testSAMLUnsignedSenderVouches() throws Exception {

+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();

+        SOAPEnvelope envelope = null;

+        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml.properties");

+

+        SAMLAssertion assertion = saml.newAssertion();

+

+        WSSAddSAMLToken wsSign = new WSSAddSAMLToken();

+

+        Document doc = unsignedEnvelope.getAsDocument();

+        log.info("Before SAMLUnsignedSenderVouches....");

+        

+        Document signedDoc = wsSign.build(doc, assertion);

+        log.info("After SAMLUnsignedSenderVouches....");

+

+        /*

+         * convert the resulting document into a message first. The toSOAPMessage()

+         * method performs the necessary c14n call to properly set up the signed

+         * document and convert it into a SOAP message. Check that the contents can't

+          * be read (cheching if we can find a specific substring). After that we extract it

+         * as a document again for further processing.

+         */

+

+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

+        if (log.isDebugEnabled()) {

+            log.debug("Unsigned SAML message (sender vouches):");

+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));

+        }

+        String encryptedString = signedMsg.getSOAPPartAsString();

+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();

+        verify(signedDoc);

+

+    }

+

+    /**

+     * Verifies the soap envelope

+     * <p/>

+     * 

+     * @param envelope 

+     * @throws Exception Thrown when there is a problem in verification

+     */

+    private void verify(Document doc) throws Exception {

+        secEngine.processSecurityHeader(doc, null, this, null);

+        SOAPUtil.updateSOAPMessage(doc, message);

+        String decryptedString = message.getSOAPPartAsString();

+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true : false);

+    }

+

+    public void handle(Callback[] callbacks)

+            throws IOException, UnsupportedCallbackException {

+        for (int i = 0; i < callbacks.length; i++) {

+            if (callbacks[i] instanceof WSPasswordCallback) {

+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

+                /*

+                 * here call a function/method to lookup the password for

+                 * the given identifier (e.g. a user name or keystore alias)

+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))

+                 * for Testing we supply a fixed name here.

+                 */

+                pc.setPassword("security");

+            } else {

+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");

+            }

+        }

+    }

+}

diff --git a/test/wssec/TestWSSecurityNewST2.java b/test/wssec/TestWSSecurityNewST2.java
new file mode 100644
index 0000000..bf5f3db
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewST2.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.ws.security.saml.SAMLIssuerFactory;
+import org.apache.ws.security.saml.SAMLIssuer;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.saml.WSSecSignatureSAML;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecHeader;
+import org.w3c.dom.Document;
+
+import org.opensaml.SAMLAssertion;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestWSSecurityNewST2 extends TestCase implements CallbackHandler {
+    private static Log log = LogFactory.getLog(TestWSSecurityNewST2.class);
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
+            "   <soapenv:Body>" +
+            "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>" +
+            "   </soapenv:Body>" +
+            "</soapenv:Envelope>";
+
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    static final Crypto crypto = CryptoFactory.getInstance("crypto.properties");
+    MessageContext msgContext;
+    Message message;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityNewST2(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityNewST2.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        message = getSOAPMessage();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws Exception if there is any problem constructing the soap envelope
+     */
+    protected Message getSOAPMessage() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg;
+    }
+
+    /**
+     * Test that encrypt and decrypt a WS-Security envelope.
+     * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric
+     * key.
+     * <p/>
+     * 
+     * @throws Exception Thrown when there is any problem in signing or verification
+     */
+    public void testSAMLSignedSenderVouches() throws Exception {
+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml3.properties");
+
+        SAMLAssertion assertion = saml.newAssertion();
+
+        String issuerKeyName = saml.getIssuerKeyName();
+        String issuerKeyPW = saml.getIssuerKeyPassword();
+        Crypto issuerCrypto = saml.getIssuerCrypto();
+        WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+        wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        
+        log.info("Before SAMLSignedSenderVouches....");
+        
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document signedDoc = wsSign.build(doc, null, assertion, issuerCrypto, issuerKeyName, issuerKeyPW, secHeader);
+        log.info("After SAMLSignedSenderVouches....");
+
+        /*
+         * convert the resulting document into a message first. The toSOAPMessage()
+         * method performs the necessary c14n call to properly set up the signed
+         * document and convert it into a SOAP message. Check that the contents can't
+          * be read (cheching if we can find a specific substring). After that we extract it
+         * as a document again for further processing.
+         */
+
+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+        if (log.isDebugEnabled()) {
+            log.debug("Signed SAML message (sender vouches):");
+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
+        }
+        String encryptedString = signedMsg.getSOAPPartAsString();
+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+        verify(signedDoc);
+
+    }
+
+    
+    /**
+     * Verifies the soap envelope
+     * <p/>
+     * 
+     * @param doc
+     * @throws Exception Thrown when there is a problem in verification
+     */
+    private void verify(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, null, this, crypto);
+        SOAPUtil.updateSOAPMessage(doc, message);
+        String decryptedString = message.getSOAPPartAsString();
+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true : false);
+    }
+
+    public void handle(Callback[] callbacks)
+            throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                /*
+                 * here call a function/method to lookup the password for
+                 * the given identifier (e.g. a user name or keystore alias)
+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+                 * for Testing we supply a fixed name here.
+                 */
+                pc.setPassword("security");
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+            }
+        }
+    }
+}
diff --git a/test/wssec/TestWSSecurityNewST3.java b/test/wssec/TestWSSecurityNewST3.java
new file mode 100644
index 0000000..9e8cfdb
--- /dev/null
+++ b/test/wssec/TestWSSecurityNewST3.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.ws.security.saml.SAMLIssuerFactory;
+import org.apache.ws.security.saml.SAMLIssuer;
+import org.apache.ws.security.saml.WSSecSignatureSAML;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.WSSecHeader;
+
+import org.w3c.dom.Document;
+
+import org.opensaml.SAMLAssertion;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ * 
+ * @author Davanum Srinivas (dims@yahoo.com)
+ */
+public class TestWSSecurityNewST3 extends TestCase implements CallbackHandler {
+    private static Log log = LogFactory.getLog(TestWSSecurityNewST3.class);
+    static final String soapMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
+            "   <soapenv:Body>" +
+            "      <ns1:testMethod xmlns:ns1=\"uri:LogTestService2\"></ns1:testMethod>" +
+            "   </soapenv:Body>" +
+            "</soapenv:Envelope>";
+
+    static final WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    static final Crypto crypto = CryptoFactory.getInstance("crypto.properties");
+    MessageContext msgContext;
+    Message message;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityNewST3(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityNewST3.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        message = getSOAPMessage();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws Exception if there is any problem constructing the soap envelope
+     */
+    protected Message getSOAPMessage() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg;
+    }
+
+    /**
+     * Test that encrypt and decrypt a WS-Security envelope.
+     * This test uses the RSA_15 alogrithm to transport (wrap) the symmetric
+     * key.
+     * <p/>
+     * 
+     * @throws Exception Thrown when there is any problem in signing or verification
+     */
+    public void testSAMLSignedKeyHolder() throws Exception {
+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+        SOAPEnvelope envelope = null;
+
+        Document doc = unsignedEnvelope.getAsDocument();
+        
+        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml4.properties");
+        // Provide info to SAML issuer that it can construct a Holder-of-key
+        // SAML token.
+        saml.setInstanceDoc(doc);
+        saml.setUserCrypto(crypto);
+        saml.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
+        SAMLAssertion assertion = saml.newAssertion();
+
+        WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+        wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        wsSign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+
+        log.info("Before SAMLSignedKeyHolder....");
+        
+        /*
+         * set up for keyHolder
+         */
+        Document signedDoc = wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
+        log.info("After SAMLSignedKeyHolder....");
+
+        /*
+         * convert the resulting document into a message first. The toSOAPMessage()
+         * method performs the necessary c14n call to properly set up the signed
+         * document and convert it into a SOAP message. Check that the contents can't
+          * be read (cheching if we can find a specific substring). After that we extract it
+         * as a document again for further processing.
+         */
+
+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+        if (log.isDebugEnabled()) {
+            log.debug("Signed SAML message (key holder):");
+            XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
+        }
+        String encryptedString = signedMsg.getSOAPPartAsString();
+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+        verify(signedDoc);
+
+    }
+
+    
+    /**
+     * Verifies the soap envelope
+     * <p/>
+     * 
+     * @param envelope 
+     * @throws Exception Thrown when there is a problem in verification
+     */
+    private void verify(Document doc) throws Exception {
+        secEngine.processSecurityHeader(doc, null, this, crypto);
+        SOAPUtil.updateSOAPMessage(doc, message);
+        String decryptedString = message.getSOAPPartAsString();
+        assertTrue(decryptedString.indexOf("LogTestService2") > 0 ? true : false);
+    }
+
+    public void handle(Callback[] callbacks)
+            throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            if (callbacks[i] instanceof WSPasswordCallback) {
+                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+                /*
+                 * here call a function/method to lookup the password for
+                 * the given identifier (e.g. a user name or keystore alias)
+                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+                 * for Testing we supply a fixed name here.
+                 */
+                pc.setPassword("security");
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+            }
+        }
+    }
+}
diff --git a/tools/changelog.xsl b/tools/changelog.xsl
new file mode 100644
index 0000000..c96073c
--- /dev/null
+++ b/tools/changelog.xsl
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xsl:stylesheet
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+    version='1.0'>
+
+<!--
+ The Apache Software License, Version 1.1
+
+ Copyright (c) 2002 The Apache Software Foundation.  All rights
+ reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ 3. The end-user documentation included with the redistribution, if
+    any, must include the following acknowlegement:
+       "This product includes software developed by the
+        Apache Software Foundation (http://www.apache.org/)."
+    Alternately, this acknowlegement may appear in the software itself,
+    if and wherever such third-party acknowlegements normally appear.
+
+ 4. The names "The Jakarta Project", "Ant", and "Apache Software
+    Foundation" must not be used to endorse or promote products derived
+    from this software without prior written permission. For written
+    permission, please contact apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache"
+    nor may "Apache" appear in their names without prior written
+    permission of the Apache Group.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ ====================================================================
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the Apache Software Foundation.  For more
+ information on the Apache Software Foundation, please see
+ <http://www.apache.org/>.
+ -->
+  <xsl:param name="title"/>
+  <xsl:param name="module"/>
+  <xsl:param name="cvsweb"/>
+
+  <xsl:output method="html" indent="yes"  encoding="US-ASCII"/>
+
+  <!-- Copy standard document elements.  Elements that
+       should be ignored must be filtered by apply-templates
+       tags. -->
+  <xsl:template match="*">
+    <xsl:copy>
+      <xsl:copy-of select="attribute::*[. != '']"/>
+      <xsl:apply-templates/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="changelog">
+    <HTML>
+      <HEAD>
+        <TITLE><xsl:value-of select="$title"/></TITLE>
+        <link href="axis.css" rel="stylesheet" type="text/css"></link>
+      </HEAD>
+      <BODY link="#000000" alink="#000000" vlink="#000000" text="#000000">
+          <h1>
+            <a name="top"><xsl:value-of select="$title"/></a>
+          </h1>
+          <p align="right">Designed for use with <a href="http://jakarta.apache.org">Ant</a>.</p>
+          <hr size="2"/>
+        <TABLE BORDER="0" WIDTH="100%" CELLPADDING="3" CELLSPACING="1">
+          
+          <xsl:apply-templates select=".//entry">
+            <xsl:sort select="date" data-type="text" order="descending"/>
+            <xsl:sort select="time" data-type="text" order="descending"/>
+          </xsl:apply-templates>
+          
+        </TABLE>
+        
+      </BODY>
+    </HTML>
+  </xsl:template>
+  
+  <xsl:template match="entry">
+    <TR>
+      <TD colspan="2" class="dateAndAuthor">
+        <xsl:value-of select="date"/><xsl:text> </xsl:text><xsl:value-of select="time"/><xsl:text> </xsl:text><xsl:value-of select="author"/>
+      </TD>
+    </TR>
+    <TR>
+      <TD width="20">
+        <xsl:text>    </xsl:text>
+      </TD>
+      <TD>
+        <pre>
+<xsl:apply-templates select="msg"/></pre>
+        <ul>
+          <xsl:apply-templates select="file"/>
+        </ul>
+      </TD>
+    </TR>
+  </xsl:template>
+
+  <xsl:template match="date">
+    <i><xsl:value-of select="."/></i>
+  </xsl:template>
+
+  <xsl:template match="time">
+    <i><xsl:value-of select="."/></i>
+  </xsl:template>
+
+  <xsl:template match="author">
+    <i>
+      <a>
+        <xsl:attribute name="href">mailto:<xsl:value-of select="."/></xsl:attribute>
+        <xsl:value-of select="."/>
+      </a>
+    </i>
+  </xsl:template>
+
+  <xsl:template match="file">
+    <li>
+      <a>
+        <xsl:choose>
+          <xsl:when test="string-length(prevrevision) = 0 ">
+            <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?rev=<xsl:value-of select="revision" />&amp;content-type=text/x-cvsweb-markup</xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?r1=<xsl:value-of select="revision" />&amp;r2=<xsl:value-of select="prevrevision"/></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:value-of select="name" /> (<xsl:value-of select="revision"/>)
+      </a>
+    </li>
+  </xsl:template>
+
+  <!-- Any elements within a msg are processed,
+       so that we can preserve HTML tags. -->
+  <xsl:template match="msg">
+    <b><xsl:apply-templates/></b>
+  </xsl:template>
+  
+</xsl:stylesheet>
+
diff --git a/webapps/axis/EchoHeaders.jws b/webapps/axis/EchoHeaders.jws
new file mode 100644
index 0000000..aa394af
--- /dev/null
+++ b/webapps/axis/EchoHeaders.jws
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.MessageContext;
+import org.apache.axis.transport.http.HTTPConstants;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Enumeration;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * class to list headers sent in request as a string array
+ */
+public class EchoHeaders {
+
+    /**
+     * demo message context stuff
+     * @return list of request headers
+     */
+    public String[] list() {
+        HttpServletRequest request = getRequest();
+        Enumeration headers=request.getHeaderNames();
+        ArrayList list=new ArrayList();
+        while (headers.hasMoreElements()) {
+            String h = (String) headers.nextElement();
+            String header=h+':'+request.getHeader(h);
+            list.add(header);
+        }
+        String[] results=new String[list.size()];
+        for(int i=0;i<list.size();i++) {
+            results[i]=(String) list.get(i);
+        }
+        return results;
+    }
+
+    /**
+     * get the caller; may involve reverse DNS
+     * @return
+     */
+    public String whoami() {
+        HttpServletRequest request = getRequest();
+        String remote=request.getRemoteHost();
+        return "Hello caller from "+remote;
+    }
+
+    /**
+     * very simple method to echo the param.
+     * @param param
+     * @return
+     */
+    public String echo(String param) {
+        return param;
+    }
+    
+    /**
+     * throw an axis fault with the text included
+     */
+    public void throwAxisFault(String param) throws AxisFault {
+        throw new AxisFault(param);
+    }
+    
+    public void throwException(String param) throws Exception { 
+        throw new Exception(param);
+    }
+
+    /**
+     * thow a runtime exception
+     */
+    public void throwRuntimeException(String param) { 
+        throw new RuntimeException(param);
+    }
+    
+    /**
+     * helper
+     * @return
+     */
+    private HttpServletRequest getRequest() {
+        MessageContext context = MessageContext.getCurrentContext();
+        HttpServletRequest req = (HttpServletRequest) context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
+        return req;
+    }
+
+}
\ No newline at end of file
diff --git a/webapps/axis/SOAPMonitorApplet.java b/webapps/axis/SOAPMonitorApplet.java
new file mode 100644
index 0000000..08b0ce1
--- /dev/null
+++ b/webapps/axis/SOAPMonitorApplet.java
@@ -0,0 +1,1482 @@
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import java.text.*;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+
+import org.apache.axis.monitor.SOAPMonitorConstants;
+
+/**
+ * This is a SOAP Mointor Applet class.  This class provides
+ * the user interface for displaying data from the SOAP
+ * monitor service.
+ *
+ * @author Brian Price (pricebe@us.ibm.com)
+ *
+ */
+public class SOAPMonitorApplet extends JApplet {
+
+    /**
+     * Private data
+     */
+    private JPanel      main_panel = null;
+    private JTabbedPane tabbed_pane = null;
+    private int         port = 0;
+    private Vector      pages = null;
+
+    /**
+     * Constructor
+     */
+    public SOAPMonitorApplet() {
+    }
+
+    /**
+     * Applet initialization
+     */
+    public void init() {
+        // Get the port to be used
+        String port_str = getParameter("port");
+        if (port_str != null) {
+            port = Integer.parseInt(port_str);
+        }
+        // Try to use the system look and feel
+        try {
+           UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+        } catch (Exception e){
+        }
+        // Create main panel to hold notebook
+        main_panel = new JPanel();
+        main_panel.setBackground(Color.white);
+        main_panel.setLayout(new BorderLayout());
+        setContentPane(main_panel);
+        // Create the notebook
+        tabbed_pane = new JTabbedPane(JTabbedPane.TOP);
+        main_panel.add(tabbed_pane,BorderLayout.CENTER);
+        // Add notebook page for default host connection
+        pages = new Vector();
+        addPage(new SOAPMonitorPage(getCodeBase().getHost()));
+    }
+
+    /**
+     * Add a page to the notebook
+     */
+    private void addPage(SOAPMonitorPage pg) {
+        tabbed_pane.addTab("  "+pg.getHost()+"  ", pg);
+        pages.addElement(pg);
+    }
+
+    /** 
+     * Applet is being displayed 
+     */
+    public void start() {
+        // Tell all pages to start talking to the server
+        Enumeration e = pages.elements();
+        while (e.hasMoreElements()) {
+            SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
+            if (pg != null) {
+                pg.start();
+            }
+        }
+    }
+
+    /*
+     * Applet is no longer displayed
+     */
+    public void stop() {
+        // Tell all pages to stop talking to the server
+        Enumeration e = pages.elements();
+        while (e.hasMoreElements()) {
+            SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
+            if (pg != null) {
+                pg.stop();
+            }
+        }
+    }
+
+    /**
+     * Applet cleanup
+     */
+    public void destroy() {
+        tabbed_pane = null;
+        main_panel = null;
+    }
+
+    /**
+     * This class provides the contents of a notebook page
+     * representing a server connection.
+     */
+    class SOAPMonitorPage extends JPanel 
+                          implements Runnable,
+                                     ListSelectionListener,
+                                     ActionListener {
+
+        /**
+         * Status Strings
+         */
+        private final String STATUS_ACTIVE    = "The SOAP Monitor is started.";
+        private final String STATUS_STOPPED   = "The SOAP Monitor is stopped.";
+        private final String STATUS_CLOSED    = "The server communication has been terminated.";
+        private final String STATUS_NOCONNECT = "The SOAP Monitor is unable to communcate with the server.";
+
+        /**
+         * Private data
+         */
+        private String                host = null;
+        private Socket                socket = null;
+        private ObjectInputStream     in = null;
+        private ObjectOutputStream    out = null;
+        private SOAPMonitorTableModel model = null;
+        private JTable                table = null;
+        private JScrollPane           scroll = null;
+        private JPanel                list_panel = null;
+        private JPanel                list_buttons = null;
+        private JButton               remove_button = null;
+        private JButton               remove_all_button = null;
+        private JButton               filter_button = null;
+        private JPanel                details_panel = null;
+        private JPanel                details_header = null;
+        private JSplitPane            details_soap = null;
+        private JPanel                details_buttons = null;
+        private JLabel                details_time = null;
+        private JLabel                details_target = null;
+        private JLabel                details_status = null;
+        private JLabel                details_time_value = null;
+        private JLabel                details_target_value = null;
+        private JLabel                details_status_value = null;
+        private EmptyBorder           empty_border = null;
+        private EtchedBorder          etched_border = null;
+        private JPanel                request_panel = null;
+        private JPanel                response_panel = null;
+        private JLabel                request_label = null;
+        private JLabel                response_label = null;
+        private SOAPMonitorTextArea   request_text = null;
+        private SOAPMonitorTextArea   response_text = null;
+        private JScrollPane           request_scroll = null;
+        private JScrollPane           response_scroll = null;
+        private JButton               layout_button = null;
+        private JSplitPane            split = null;
+        private JPanel                status_area = null;
+        private JPanel                status_buttons = null;
+        private JButton               start_button = null;
+        private JButton               stop_button = null;
+        private JLabel                status_text = null;
+        private JPanel                status_text_panel = null;
+        private SOAPMonitorFilter     filter = null;
+        private GridBagLayout         details_header_layout = null;
+        private GridBagConstraints    details_header_constraints = null;
+        private JCheckBox             reflow_xml = null;
+
+        /**
+         * Constructor (create and layout page)
+         */
+        public SOAPMonitorPage(String host_name) {
+            host = host_name;
+            // Set up default filter (show all messages)
+            filter = new SOAPMonitorFilter();
+            // Use borders to help improve appearance
+            etched_border = new EtchedBorder();
+            // Build top portion of split (list panel) 
+            model = new SOAPMonitorTableModel();
+            table = new JTable(model);
+            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+            table.setRowSelectionInterval(0,0);
+            table.setPreferredScrollableViewportSize(new Dimension(600, 96));
+            table.getSelectionModel().addListSelectionListener(this);
+            scroll = new JScrollPane(table);
+            remove_button = new JButton("Remove");
+            remove_button.addActionListener(this);
+            remove_button.setEnabled(false);
+            remove_all_button = new JButton("Remove All");
+            remove_all_button.addActionListener(this);
+            filter_button = new JButton("Filter ...");
+            filter_button.addActionListener(this);
+            list_buttons = new JPanel();
+            list_buttons.setLayout(new FlowLayout());
+            list_buttons.add(remove_button);
+            list_buttons.add(remove_all_button);
+            list_buttons.add(filter_button);
+            list_panel = new JPanel();
+            list_panel.setLayout(new BorderLayout());
+            list_panel.add(scroll,BorderLayout.CENTER);
+            list_panel.add(list_buttons, BorderLayout.SOUTH);
+            list_panel.setBorder(empty_border);
+            // Build bottom portion of split (message details) 
+            details_time = new JLabel("Time: ", SwingConstants.RIGHT);
+            details_target = new JLabel("Target Service: ", SwingConstants.RIGHT);
+            details_status = new JLabel("Status: ", SwingConstants.RIGHT);
+            details_time_value = new JLabel();
+            details_target_value = new JLabel();
+            details_status_value = new JLabel();
+            Dimension preferred_size = details_time.getPreferredSize();
+            preferred_size.width = 1;
+            details_time.setPreferredSize(preferred_size); 
+            details_target.setPreferredSize(preferred_size); 
+            details_status.setPreferredSize(preferred_size); 
+            details_time_value.setPreferredSize(preferred_size); 
+            details_target_value.setPreferredSize(preferred_size); 
+            details_status_value.setPreferredSize(preferred_size);
+            details_header = new JPanel();
+            details_header_layout = new GridBagLayout();
+            details_header.setLayout(details_header_layout);
+            details_header_constraints = new GridBagConstraints();
+            details_header_constraints.fill=GridBagConstraints.BOTH;
+            details_header_constraints.weightx=0.5;
+            details_header_layout.setConstraints(details_time,details_header_constraints);
+            details_header.add(details_time);
+            details_header_layout.setConstraints(details_time_value,details_header_constraints);
+            details_header.add(details_time_value);
+            details_header_layout.setConstraints(details_target,details_header_constraints);
+            details_header.add(details_target);
+            details_header_constraints.weightx=1.0;
+            details_header_layout.setConstraints(details_target_value,details_header_constraints);
+            details_header.add(details_target_value);
+            details_header_constraints.weightx=.5;
+            details_header_layout.setConstraints(details_status,details_header_constraints);
+            details_header.add(details_status);
+            details_header_layout.setConstraints(details_status_value,details_header_constraints);
+            details_header.add(details_status_value);
+            details_header.setBorder(etched_border);
+            request_label = new JLabel("SOAP Request", SwingConstants.CENTER);
+            request_text = new SOAPMonitorTextArea();
+            request_text.setEditable(false);
+            request_scroll = new JScrollPane(request_text);
+            request_panel = new JPanel();
+            request_panel.setLayout(new BorderLayout());
+            request_panel.add(request_label, BorderLayout.NORTH);
+            request_panel.add(request_scroll, BorderLayout.CENTER);
+            response_label = new JLabel("SOAP Response", SwingConstants.CENTER);
+            response_text = new SOAPMonitorTextArea();
+            response_text.setEditable(false);
+            response_scroll = new JScrollPane(response_text);
+            response_panel = new JPanel();
+            response_panel.setLayout(new BorderLayout());
+            response_panel.add(response_label, BorderLayout.NORTH);
+            response_panel.add(response_scroll, BorderLayout.CENTER);
+            details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+            details_soap.setTopComponent(request_panel);
+            details_soap.setRightComponent(response_panel);
+            details_soap.setResizeWeight(.5);
+            details_panel = new JPanel();
+            layout_button = new JButton("Switch Layout");
+            layout_button.addActionListener(this);
+            reflow_xml = new JCheckBox("Reflow XML text");
+            reflow_xml.addActionListener(this);
+            details_buttons = new JPanel();
+            details_buttons.setLayout(new FlowLayout());
+            details_buttons.add(reflow_xml);
+            details_buttons.add(layout_button);
+            details_panel.setLayout(new BorderLayout());
+            details_panel.add(details_header,BorderLayout.NORTH);
+            details_panel.add(details_soap,BorderLayout.CENTER);
+            details_panel.add(details_buttons,BorderLayout.SOUTH);
+            details_panel.setBorder(empty_border);
+            // Add the two parts to the age split pane
+            split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+            split.setTopComponent(list_panel);
+            split.setRightComponent(details_panel);
+            // Build status area
+            start_button = new JButton("Start");
+            start_button.addActionListener(this);
+            stop_button = new JButton("Stop");
+            stop_button.addActionListener(this);
+            status_buttons = new JPanel();
+            status_buttons.setLayout(new FlowLayout());
+            status_buttons.add(start_button);
+            status_buttons.add(stop_button);
+            status_text = new JLabel();
+            status_text.setBorder(new BevelBorder(BevelBorder.LOWERED));
+            status_text_panel = new JPanel();
+            status_text_panel.setLayout(new BorderLayout());
+            status_text_panel.add(status_text, BorderLayout.CENTER);
+            status_text_panel.setBorder(empty_border);
+            status_area = new JPanel();
+            status_area.setLayout(new BorderLayout());
+            status_area.add(status_buttons, BorderLayout.WEST);
+            status_area.add(status_text_panel, BorderLayout.CENTER);
+            status_area.setBorder(etched_border);
+            // Add the split and status area to page
+            setLayout(new BorderLayout());
+            add(split, BorderLayout.CENTER);
+            add(status_area, BorderLayout.SOUTH);
+        }
+
+        /**
+         * Get the name of the host we are displaying
+         */
+        public String getHost() {
+            return host;
+        }
+
+        /**
+         * Set the status text
+         */
+        public void setStatus(String txt) {
+            status_text.setForeground(Color.black);
+            status_text.setText("  "+txt);
+        }
+
+        /**
+         * Set the status text to an error
+         */
+        public void setErrorStatus(String txt) {
+            status_text.setForeground(Color.red);
+            status_text.setText("  "+txt);
+        }
+
+        /**
+         * Start talking to the server
+         */
+        public void start() {
+            String codehost = getCodeBase().getHost();
+            if (socket == null) {
+                try {
+                    // Open the socket to the server
+                    socket = new Socket(codehost, port);
+                    // Create output stream
+                    out = new ObjectOutputStream(socket.getOutputStream());
+                    out.flush();
+                    // Create input stream and start background
+                    // thread to read data from the server
+                    in = new ObjectInputStream(socket.getInputStream());
+                    new Thread(this).start();
+                } catch (Exception e) {
+                    // Exceptions here are unexpected, but we can't
+                    // really do anything (so just write it to stdout
+                    // in case someone cares and then ignore it)
+                    System.out.println("Exception! "+e.toString());
+                    e.printStackTrace();
+                    setErrorStatus(STATUS_NOCONNECT);
+                    socket = null;
+                }
+            } else {
+                // Already started
+            }
+            if (socket != null) {
+                // Make sure the right buttons are enabled
+                start_button.setEnabled(false);
+                stop_button.setEnabled(true);
+                setStatus(STATUS_ACTIVE);
+            }
+        }
+
+        /**
+         * Stop talking to the server
+         */
+        public void stop() {
+            if (socket != null) {
+                // Close all the streams and socket
+                if (out != null) {
+                    try {
+                        out.close();
+                    } catch (IOException ioe) {
+                    }
+                    out = null;
+                }
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException ioe) {
+                    }
+                    in = null;
+                }
+                if (socket != null) {
+                    try {
+                        socket.close();
+                    } catch (IOException ioe) {
+                    }
+                    socket = null;
+                }
+            } else {
+                // Already stopped
+            }
+            // Make sure the right buttons are enabled
+            start_button.setEnabled(true);
+            stop_button.setEnabled(false);
+            setStatus(STATUS_STOPPED);
+        }
+
+        /**
+         * Background thread used to receive data from
+         * the server.
+         */
+        public void run() {
+            Long            id;
+            Integer         message_type;
+            String          target;
+            String          soap;
+            SOAPMonitorData data;
+            int             selected;
+            int             row;
+            boolean         update_needed;
+            while (socket != null) {
+                try {
+                    // Get the data from the server
+                    message_type = (Integer) in.readObject();
+                    // Process the data depending on its type
+                    switch (message_type.intValue()) {
+                        case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:
+                            // Get the id, target and soap info
+                            id = (Long) in.readObject();
+                            target = (String) in.readObject();
+                            soap = (String) in.readObject();
+                            // Add new request data to the table
+                            data = new SOAPMonitorData(id,target,soap);
+                            model.addData(data);
+                            // If "most recent" selected then update
+                            // the details area if needed
+                            selected = table.getSelectedRow();
+                            if ((selected == 0) && model.filterMatch(data)) {
+                                valueChanged(null);
+                            }
+                            break;
+                        case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:
+                            // Get the id and soap info
+                            id = (Long) in.readObject();
+                            soap = (String) in.readObject();
+                            data = model.findData(id);
+                            if (data != null) {
+                                update_needed = false;
+                                // Get the selected row
+                                selected = table.getSelectedRow();
+                                // If "most recent", then always
+                                // update details area
+                                if (selected == 0) {
+                                    update_needed = true;
+                                }
+                                // If the data being updated is
+                                // selected then update details
+                                row = model.findRow(data);
+                                if ((row != -1) && (row == selected)) {
+                                    update_needed = true;
+                                }
+                                // Set the response and update table
+                                data.setSOAPResponse(soap);
+                                model.updateData(data);
+                                // Refresh details area (if needed)
+                                if (update_needed) {
+                                    valueChanged(null);
+                                }
+                            }
+                            break;
+                    }
+
+                } catch (Exception e) {
+                    // Exceptions are expected here when the
+                    // server communication has been terminated.
+                    if (stop_button.isEnabled()) {
+                        stop();
+                        setErrorStatus(STATUS_CLOSED);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Listener to handle table selection changes
+         */
+        public void valueChanged(ListSelectionEvent e) {
+            int row = table.getSelectedRow();
+            // Check if they selected a specific row
+            if (row > 0) {
+                remove_button.setEnabled(true);
+            } else {
+                remove_button.setEnabled(false);
+            }
+            // Check for "most recent" selection
+            if (row == 0) {
+                row = model.getRowCount() - 1;
+                if (row == 0) {
+                    row = -1;
+                }
+            }
+            if (row == -1) {
+                // Clear the details panel
+                details_time_value.setText("");
+                details_target_value.setText("");
+                details_status_value.setText("");
+                request_text.setText("");
+                response_text.setText("");
+            } else {
+                // Show the details for the row
+                SOAPMonitorData soap = model.getData(row);
+                details_time_value.setText(soap.getTime());
+                details_target_value.setText(soap.getTargetService());
+                details_status_value.setText(soap.getStatus());
+                if (soap.getSOAPRequest() == null) {
+                    request_text.setText("");
+                } else {
+                    request_text.setText(soap.getSOAPRequest());
+                    request_text.setCaretPosition(0);
+                }
+                if (soap.getSOAPResponse() == null) {
+                    response_text.setText("");
+                } else {
+                    response_text.setText(soap.getSOAPResponse());
+                    response_text.setCaretPosition(0);
+                }
+            }
+        }
+
+        /**
+         * Listener to handle button actions
+         */
+        public void actionPerformed(ActionEvent e) {
+            // Check if the user pressed the remove button
+            if (e.getSource() == remove_button) {
+                int row = table.getSelectedRow();
+                model.removeRow(row);
+                table.clearSelection();
+                table.repaint();
+                valueChanged(null);
+            }
+            // Check if the user pressed the remove all button
+            if (e.getSource() == remove_all_button) {
+                model.clearAll();
+                table.setRowSelectionInterval(0,0);
+                table.repaint();
+                valueChanged(null);
+            }
+            // Check if the user pressed the filter button
+            if (e.getSource() == filter_button) {
+                filter.showDialog();
+                if (filter.okPressed()) {
+                    // Update the display with new filter
+                    model.setFilter(filter);
+                    table.repaint();
+                }
+            }
+            // Check if the user pressed the start button
+            if (e.getSource() == start_button) {
+                start();
+            }
+            // Check if the user pressed the stop button
+            if (e.getSource() == stop_button) {
+                stop();
+            }
+            // Check if the user wants to switch layout
+            if (e.getSource() == layout_button) {
+                details_panel.remove(details_soap);
+                details_soap.removeAll();
+                if (details_soap.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
+                    details_soap = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+                } else {
+                    details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+                }
+                details_soap.setTopComponent(request_panel);
+                details_soap.setRightComponent(response_panel);
+                details_soap.setResizeWeight(.5);
+                details_panel.add(details_soap, BorderLayout.CENTER);
+                details_panel.validate();
+                details_panel.repaint();
+            }
+            // Check if the user is changing the reflow option
+            if (e.getSource() == reflow_xml) {
+                request_text.setReflowXML(reflow_xml.isSelected());
+                response_text.setReflowXML(reflow_xml.isSelected());
+            }
+        }
+    }
+
+    /**
+     * This class represend the data for a SOAP request/response pair
+     */
+    class SOAPMonitorData {
+
+        /**
+         * Private data
+         */
+        private Long    id;
+        private String  time;
+        private String  target;
+        private String  soap_request;
+        private String  soap_response;
+
+        /**
+         * Constructor
+         */
+        public SOAPMonitorData(Long id, String target, String soap_request) {
+            this.id = id;
+            // A null id is used to signal that the "most recent" entry
+            // is being created.
+            if (id == null) {
+                this.time = "Most Recent";
+                this.target = "---";
+                this.soap_request = null;
+                this.soap_response = null;
+            } else {
+                this.time = DateFormat.getTimeInstance().format(new Date());
+                this.target = target;
+                this.soap_request = soap_request;
+                this.soap_response = null;
+            }
+        }
+
+        /**
+         * Get the id for the SOAP message
+         */
+        public Long getId() {
+            return id;
+        }
+
+        /**
+         * Get the time the SOAP request was received by the applet
+         */
+        public String getTime() {
+            return time;
+        }
+
+        /**
+         * Get the SOAP request target service name
+         */
+        public String getTargetService() {
+            return target;
+        }
+
+        /**
+         * Get the status of the request
+         */
+        public String getStatus() {
+            String status = "---";
+            if (id != null) {
+                status = "Complete";
+                if (soap_response == null) {
+                    status = "Active";
+                }
+            }
+            return status;
+        }
+
+        /**
+         * Get the request SOAP contents
+         */
+        public String getSOAPRequest() {
+            return soap_request;
+        }
+
+        /**
+         * Set the resposne SOAP contents
+         */
+        public void setSOAPResponse(String response) {
+            soap_response = response;
+        }
+
+        /**
+         * Get the response SOAP contents
+         */
+        public String getSOAPResponse() {
+            return soap_response;
+        }
+    }
+
+    /**
+     * This table model is used to manage the table displayed
+     * at the top of the page to show all the SOAP messages
+     * we have received and to control which message details are
+     * to be displayed on the bottom of the page.
+     */
+    class SOAPMonitorTableModel extends AbstractTableModel {
+
+        /**
+         * Column titles
+         */
+        private final String[] column_names = { "Time",
+                                                "Target Service",
+                                                "Status" };
+        /**                                        
+         * Private data
+         */
+        private Vector  data;
+        private Vector  filter_include;
+        private Vector  filter_exclude;
+        private boolean filter_active;
+        private boolean filter_complete;
+        private Vector  filter_data;
+
+        /**
+         * Constructor
+         */
+        public SOAPMonitorTableModel() {
+            data = new Vector();
+            // Add "most recent" entry to top of table
+            SOAPMonitorData soap = new SOAPMonitorData(null,null,null);
+            data.addElement(soap);
+            filter_include = null;
+            filter_exclude = null;
+            filter_active = false;
+            filter_complete = false;
+            filter_data = null;
+            // By default, exclude NotificationService and
+            // EventViewerService messages
+            filter_exclude = new Vector();
+            filter_exclude.addElement("NotificationService");
+            filter_exclude.addElement("EventViewerService");
+            filter_data = new Vector();
+            filter_data.addElement(soap);
+        }
+
+        /**
+         * Get column count (part of table model interface)
+         */
+        public int getColumnCount() {
+            return column_names.length;
+        }
+        
+        /**
+         * Get row count (part of table model interface)
+         */
+        public int getRowCount() {
+            int count = data.size();
+            if (filter_data != null) {
+                count = filter_data.size();
+            }
+            return count;
+        }
+
+        /**
+         * Get column name (part of table model interface)
+         */
+        public String getColumnName(int col) {
+            return column_names[col];
+        }
+
+        /**
+         * Get value at (part of table model interface)
+         */
+        public Object getValueAt(int row, int col) {
+            SOAPMonitorData soap;
+            String          value = null;
+            soap = (SOAPMonitorData) data.elementAt(row);
+            if (filter_data != null) {
+                soap = (SOAPMonitorData) filter_data.elementAt(row);
+            }
+            switch (col) {
+                case 0:
+                    value = soap.getTime();
+                    break;
+                case 1:
+                    value = soap.getTargetService();
+                    break;
+                case 2:
+                    value = soap.getStatus();
+                    break;
+            }
+            return value;
+        }
+
+        /**
+         * Check if soap data matches filter 
+         */
+        public boolean filterMatch(SOAPMonitorData soap) {
+            boolean match = true;
+            if (filter_include != null) {
+                // Check for service match
+                Enumeration e = filter_include.elements();
+                match = false;
+                while (e.hasMoreElements() && !match) {
+                    String service = (String) e.nextElement();
+                    if (service.equals(soap.getTargetService())) {
+                        match = true;
+                    }
+                }
+            }
+            if (filter_exclude != null) {
+                // Check for service match
+                Enumeration e = filter_exclude.elements();
+                while (e.hasMoreElements() && match) {
+                    String service = (String) e.nextElement();
+                    if (service.equals(soap.getTargetService())) {
+                        match = false;
+                    }
+                }
+            }
+            if (filter_active) {
+                // Check for active status match
+                if (soap.getSOAPResponse() != null) {
+                    match = false;
+                }
+            }
+            if (filter_complete) {
+                // Check for complete status match
+                if (soap.getSOAPResponse() == null) {
+                    match = false;
+                }
+            }
+            // The "most recent" is always a match
+            if (soap.getId() == null) {
+                match = true;
+            }
+            return match;
+        }
+
+        /**
+         * Add data to the table as a new row
+         */
+        public void addData(SOAPMonitorData soap) {
+            int row = data.size();
+            data.addElement(soap);
+            if (filter_data != null) {
+                if (filterMatch(soap)) {
+                    row = filter_data.size();
+                    filter_data.addElement(soap);
+                    fireTableRowsInserted(row,row);
+                }
+            } else {
+                fireTableRowsInserted(row,row);
+            }
+        }
+
+        /**
+         * Find the data for a given id
+         */
+        public SOAPMonitorData findData(Long id) {
+            SOAPMonitorData soap = null;
+            for (int row=data.size(); (row > 0) && (soap == null); row--) {
+                soap = (SOAPMonitorData) data.elementAt(row-1);
+                if (soap.getId().longValue() != id.longValue()) {
+                    soap = null;
+                }
+            }
+            return soap;
+        }
+
+        /**
+         * Find the row in the table for a given message id
+         */
+        public int findRow(SOAPMonitorData soap) {
+            int row = -1;
+            if (filter_data != null) {
+                row = filter_data.indexOf(soap);
+            } else {
+                row = data.indexOf(soap);
+            }
+            return row;
+        }
+
+        /**
+         * Remove all messages from the table (but leave "most recent")
+         */
+        public void clearAll() {
+            int last_row = data.size() - 1;
+            if (last_row > 0) {
+                data.removeAllElements();
+                SOAPMonitorData soap = new SOAPMonitorData(null,null,null);
+                data.addElement(soap);
+                if (filter_data != null) {
+                    filter_data.removeAllElements();
+                    filter_data.addElement(soap);
+                }
+                fireTableDataChanged();
+            }
+        }
+
+        /**
+         * Remove a message from the table
+         */
+        public void removeRow(int row) {
+            SOAPMonitorData soap = null;
+            if (filter_data == null) {
+                soap = (SOAPMonitorData) data.elementAt(row);
+                data.remove(soap);
+            } else {
+                soap = (SOAPMonitorData) filter_data.elementAt(row);
+                filter_data.remove(soap);
+                data.remove(soap);
+            }         
+            fireTableRowsDeleted(row,row);
+        }
+
+        /**
+         * Set a new filter
+         */
+        public void setFilter(SOAPMonitorFilter filter) {
+            // Save new filter criteria
+            filter_include = filter.getFilterIncludeList();
+            filter_exclude = filter.getFilterExcludeList();
+            filter_active = filter.getFilterActive();
+            filter_complete = filter.getFilterComplete();
+            applyFilter();
+        }
+
+        /**
+         * Refilter the list of messages
+         */
+        public void applyFilter() {
+            // Re-filter using new criteria
+            filter_data = null;
+            if ((filter_include != null) || 
+                (filter_exclude != null) ||
+                 filter_active || filter_complete ) {
+                filter_data = new Vector();
+                Enumeration e = data.elements();
+                SOAPMonitorData soap;
+                while (e.hasMoreElements()) {
+                    soap = (SOAPMonitorData) e.nextElement();
+                    if (filterMatch(soap)) {
+                        filter_data.addElement(soap);
+                    }
+                }
+            }
+            fireTableDataChanged();
+        }
+
+        /**
+         * Get the data for a row
+         */
+        public SOAPMonitorData getData(int row) {
+            SOAPMonitorData soap = null;
+            if (filter_data == null) {
+                soap = (SOAPMonitorData) data.elementAt(row);
+            } else {
+                soap = (SOAPMonitorData) filter_data.elementAt(row);
+            }
+            return soap;
+        }
+
+        /**
+         * Update a message
+         */
+        public void updateData (SOAPMonitorData soap) {
+           int row;
+           if (filter_data == null) {
+               // No filter, so just fire table updated
+               row = data.indexOf(soap);
+               if (row != -1) {
+                   fireTableRowsUpdated(row,row);
+               }
+           } else {
+               // Check if the row was being displayed
+               row = filter_data.indexOf(soap);
+               if (row == -1) {
+                   // Row was not displayed, so check for if it
+                   // now needs to be displayed
+                   if (filterMatch(soap)) {
+                       int index = -1;
+                       row = data.indexOf(soap) + 1;
+                       while ((row < data.size()) && (index == -1)) {
+                           index = filter_data.indexOf(data.elementAt(row));
+                           if (index != -1) {                   
+                               // Insert at this location
+                               filter_data.add(index,soap);
+                           }
+                           row++;
+                       }
+                       if (index == -1) {
+                           // Insert at end
+                           index = filter_data.size();
+                           filter_data.addElement(soap);
+                       }
+                       fireTableRowsInserted(index,index);
+                   }
+               } else {
+                   // Row was displayed, so check if it needs to
+                   // be updated or removed
+                   if (filterMatch(soap)) {
+                       fireTableRowsUpdated(row,row);
+                   } else {
+                       filter_data.remove(soap);
+                       fireTableRowsDeleted(row,row);
+                   }
+               }
+           }
+        }
+
+    }
+
+    /**
+     * Panel with checkbox and list
+     */
+    class ServiceFilterPanel extends JPanel 
+                             implements ActionListener,
+                                        ListSelectionListener,
+                                        DocumentListener {
+
+        private JCheckBox    service_box = null;
+        private Vector       filter_list = null;
+        private Vector       service_data = null;
+        private JList        service_list = null;
+        private JScrollPane  service_scroll = null;
+        private JButton      remove_service_button = null;
+        private JPanel       remove_service_panel = null;
+        private EmptyBorder  indent_border = null;
+        private EmptyBorder  empty_border = null;
+        private JPanel       service_area = null;
+        private JPanel       add_service_area = null;
+        private JTextField   add_service_field = null;
+        private JButton      add_service_button = null;
+        private JPanel       add_service_panel = null;
+
+        /**
+         * Constructor
+         */
+        public ServiceFilterPanel(String text, Vector list) {
+            empty_border = new EmptyBorder(5,5,0,5);
+            indent_border = new EmptyBorder(5,25,5,5);
+            service_box = new JCheckBox(text);
+            service_box.addActionListener(this);
+            service_data = new Vector();
+            if (list != null) {
+                service_box.setSelected(true);
+                service_data = (Vector) list.clone();
+            }
+            service_list = new JList(service_data);
+            service_list.setBorder(new EtchedBorder());
+            service_list.setVisibleRowCount(5);
+            service_list.addListSelectionListener(this);
+            service_list.setEnabled(service_box.isSelected());
+            service_scroll = new JScrollPane(service_list);
+            service_scroll.setBorder(new EtchedBorder());
+            remove_service_button = new JButton("Remove");
+            remove_service_button.addActionListener(this);
+            remove_service_button.setEnabled(false);
+            remove_service_panel = new JPanel();
+            remove_service_panel.setLayout(new FlowLayout());
+            remove_service_panel.add(remove_service_button);
+            service_area = new JPanel();
+            service_area.setLayout(new BorderLayout());
+            service_area.add(service_scroll, BorderLayout.CENTER);
+            service_area.add(remove_service_panel, BorderLayout.EAST);
+            service_area.setBorder(indent_border);
+            add_service_field = new JTextField();
+            add_service_field.addActionListener(this);
+            add_service_field.getDocument().addDocumentListener(this);
+            add_service_field.setEnabled(service_box.isSelected());
+            add_service_button = new JButton("Add");
+            add_service_button.addActionListener(this);
+            add_service_button.setEnabled(false);
+            add_service_panel = new JPanel();
+            add_service_panel.setLayout(new BorderLayout());
+            JPanel dummy = new JPanel();
+            dummy.setBorder(empty_border);
+            add_service_panel.add(dummy, BorderLayout.WEST);
+            add_service_panel.add(add_service_button, BorderLayout.EAST);
+            add_service_area = new JPanel();
+            add_service_area.setLayout(new BorderLayout());
+            add_service_area.add(add_service_field, BorderLayout.CENTER);
+            add_service_area.add(add_service_panel, BorderLayout.EAST);
+            add_service_area.setBorder(indent_border);
+            setLayout(new BorderLayout());
+            add(service_box, BorderLayout.NORTH);
+            add(service_area, BorderLayout.CENTER);
+            add(add_service_area, BorderLayout.SOUTH);
+            setBorder(empty_border);
+        }
+
+        /**
+         * Get the current list of services
+         */
+        public Vector getServiceList() {
+            Vector list = null;
+            if (service_box.isSelected()) {
+                list = service_data;
+            }
+            return list;
+        }
+
+        /**
+         * Listener to handle button actions
+         */
+        public void actionPerformed(ActionEvent e) {
+            // Check if the user changed the service filter option
+            if (e.getSource() == service_box) {
+                service_list.setEnabled(service_box.isSelected());
+                service_list.clearSelection();
+                remove_service_button.setEnabled(false);
+                add_service_field.setEnabled(service_box.isSelected());
+                add_service_field.setText("");
+                add_service_button.setEnabled(false);
+            }
+            // Check if the user pressed the add service button
+            if ((e.getSource() == add_service_button) ||
+                (e.getSource() == add_service_field)) {
+                String text = add_service_field.getText();
+                if ((text != null) && (text.length() > 0)) {
+                    service_data.addElement(text);
+                    service_list.setListData(service_data);
+                }
+                add_service_field.setText("");
+                add_service_field.requestFocus();
+            }
+            // Check if the user pressed the remove service button
+            if (e.getSource() == remove_service_button) {
+                Object[] sels = service_list.getSelectedValues();
+                for (int i=0; i<sels.length; i++) {
+                    service_data.removeElement(sels[i]);
+                }
+                service_list.setListData(service_data);
+                service_list.clearSelection();
+            }
+        }
+
+        /**
+         * Handle changes to the text field
+         */
+        public void changedUpdate(DocumentEvent e) {
+            String text = add_service_field.getText();
+            if ((text != null) && (text.length() > 0)) {
+                add_service_button.setEnabled(true);
+            } else {
+                add_service_button.setEnabled(false);
+            }
+        }
+
+        /**
+         * Handle changes to the text field
+         */
+        public void insertUpdate(DocumentEvent e) {
+            changedUpdate(e);
+        }
+
+        /**
+         * Handle changes to the text field
+         */
+        public void removeUpdate(DocumentEvent e) {
+            changedUpdate(e);
+        }
+
+        /**
+         * Listener to handle service list selection changes
+         */
+        public void valueChanged(ListSelectionEvent e) {
+            if (service_list.getSelectedIndex() == -1) {
+                remove_service_button.setEnabled(false);
+            } else {
+                remove_service_button.setEnabled(true);
+            }
+        }
+    }
+
+    /**
+     * Class for showing the filter dialog
+     */
+    class SOAPMonitorFilter implements ActionListener {
+
+        /**
+         * Private data
+         */
+        private JDialog            dialog = null;
+        private JPanel             panel = null;
+        private JPanel             buttons = null;
+        private JButton            ok_button = null;
+        private JButton            cancel_button = null;
+        private ServiceFilterPanel include_panel = null;
+        private ServiceFilterPanel exclude_panel = null;
+        private JPanel             status_panel = null;
+        private JCheckBox          status_box = null;
+        private EmptyBorder  empty_border = null;
+        private EmptyBorder  indent_border = null;
+        private JPanel             status_options = null;
+        private ButtonGroup        status_group = null;
+        private JRadioButton       status_active = null;
+        private JRadioButton       status_complete = null;
+        private Vector             filter_include_list = null;
+        private Vector             filter_exclude_list = null;
+        private boolean            filter_active = false;
+        private boolean            filter_complete = false;
+        private boolean            ok_pressed = false;
+
+        /**
+         * Constructor
+         */
+        public SOAPMonitorFilter() {
+            // By default, exclude NotificationService and
+            // EventViewerService messages
+            filter_exclude_list = new Vector();
+            filter_exclude_list.addElement("NotificationService");
+            filter_exclude_list.addElement("EventViewerService");
+        }
+
+        /**
+         * Get list of services to be included
+         */
+        public Vector getFilterIncludeList() {
+            return filter_include_list;
+        }
+
+        /**
+         * Get list of services to be excluded
+         */
+        public Vector getFilterExcludeList() {
+            return filter_exclude_list;
+        }
+
+        /**
+         * Check if filter active messages
+         */
+        public boolean getFilterActive() {
+            return filter_active;
+        }
+
+        /**
+         * Check if filter complete messages
+         */
+        public boolean getFilterComplete() {
+            return filter_complete;
+        }
+
+        /**
+         * Show the filter dialog
+         */
+        public void showDialog() {
+            empty_border = new EmptyBorder(5,5,0,5);
+            indent_border = new EmptyBorder(5,25,5,5);
+            include_panel = new ServiceFilterPanel("Include messages based on target service:",
+                                                   filter_include_list);
+            exclude_panel = new ServiceFilterPanel("Exclude messages based on target service:",
+                                                   filter_exclude_list);
+            status_box = new JCheckBox("Filter messages based on status:");
+            status_box.addActionListener(this);
+            status_active = new JRadioButton("Active messages only");
+            status_active.setSelected(true);
+            status_active.setEnabled(false);
+            status_complete = new JRadioButton("Complete messages only");
+            status_complete.setEnabled(false);
+            status_group = new ButtonGroup();
+            status_group.add(status_active);
+            status_group.add(status_complete);
+            if (filter_active || filter_complete) {
+                status_box.setSelected(true);
+                status_active.setEnabled(true);
+                status_complete.setEnabled(true);
+                if (filter_complete) {
+                    status_complete.setSelected(true);
+                }
+            }
+            status_options = new JPanel();
+            status_options.setLayout(new BoxLayout(status_options, BoxLayout.Y_AXIS));
+            status_options.add(status_active);
+            status_options.add(status_complete);
+            status_options.setBorder(indent_border);
+            status_panel = new JPanel();
+            status_panel.setLayout(new BorderLayout());
+            status_panel.add(status_box, BorderLayout.NORTH);
+            status_panel.add(status_options, BorderLayout.CENTER);
+            status_panel.setBorder(empty_border);
+            ok_button = new JButton("Ok");
+            ok_button.addActionListener(this);
+            cancel_button = new JButton("Cancel");
+            cancel_button.addActionListener(this);
+            buttons = new JPanel();
+            buttons.setLayout(new FlowLayout());
+            buttons.add(ok_button);
+            buttons.add(cancel_button);
+            panel = new JPanel();
+            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+            panel.add(include_panel);
+            panel.add(exclude_panel);
+            panel.add(status_panel);
+            panel.add(buttons);
+            dialog = new JDialog();
+            dialog.setTitle("SOAP Monitor Filter");
+            dialog.setContentPane(panel);
+            dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+            dialog.setModal(true);
+            dialog.pack();
+            Dimension d = dialog.getToolkit().getScreenSize();
+            dialog.setLocation((d.width-dialog.getWidth())/2,
+                               (d.height-dialog.getHeight())/2);
+            ok_pressed = false;
+            dialog.show();
+        }
+
+        /**
+         * Listener to handle button actions
+         */
+        public void actionPerformed(ActionEvent e) {
+            // Check if the user pressed the ok button
+            if (e.getSource() == ok_button) {
+                filter_include_list = include_panel.getServiceList();
+                filter_exclude_list = exclude_panel.getServiceList();
+                if (status_box.isSelected()) {
+                    filter_active = status_active.isSelected();
+                    filter_complete = status_complete.isSelected();
+                } else {
+                    filter_active = false;
+                    filter_complete = false;
+                }
+                ok_pressed = true;
+                dialog.dispose();
+            }
+            // Check if the user pressed the cancel button
+            if (e.getSource() == cancel_button) {
+                dialog.dispose();
+            }
+            // Check if the user changed the status filter option
+            if (e.getSource() == status_box) {
+                status_active.setEnabled(status_box.isSelected());
+                status_complete.setEnabled(status_box.isSelected());
+            }
+        }
+
+        /**
+         * Check if the user pressed the ok button
+         */
+        public boolean okPressed() {
+            return ok_pressed;
+        }
+    }
+
+    /**
+     * Text panel class that supports XML reflow
+     */
+    class SOAPMonitorTextArea extends JTextArea {
+
+        /**
+         * Private data
+         */
+        private boolean format = false;
+        private String  original = "";
+        private String  formatted = null; 
+
+        /**
+         * Constructor
+         */
+        public SOAPMonitorTextArea() {
+        }
+
+        /** 
+         * Override setText to do formatting
+         */
+        public void setText(String text) {
+            original = text;
+            formatted = null;
+            if (format) {
+                doFormat();
+                super.setText(formatted);
+            } else {
+                super.setText(original);
+            }
+        }
+
+        /**
+         * Turn reflow on or off
+         */
+        public void setReflowXML(boolean reflow) {
+            format = reflow;
+            if (format) {
+                if (formatted == null) {
+                    doFormat();
+                }
+                super.setText(formatted);
+            } else {
+                super.setText(original);
+            }
+        }
+
+        /**
+         * Reflow XML
+         */
+        public void doFormat() {
+            Vector       parts = new Vector();
+            char[]       chars = original.toCharArray();
+            int          index = 0;
+            int          first = 0;
+            String       part = null;
+            while (index < chars.length) {
+                // Check for start of tag
+                if (chars[index] == '<') {
+                    // Did we have data before this tag?
+                    if (first < index) {
+                        part = new String(chars,first,index-first);
+                        part = part.trim();
+                        // Save non-whitespace data
+                        if (part.length() > 0) {
+                            parts.addElement(part);
+                        }
+                    }
+                    // Save the start of tag
+                    first = index;
+                }
+                // Check for end of tag
+                if (chars[index] == '>') {
+                    // Save the tag
+                    part = new String(chars,first,index-first+1);
+                    parts.addElement(part);
+                    first = index+1;
+                }
+                // Check for end of line
+                if ((chars[index] == '\n') || (chars[index] == '\r')) {
+                    // Was there data on this line?
+                    if (first < index) {
+                        part = new String(chars,first,index-first);
+                        part = part.trim();
+                        // Save non-whitespace data
+                        if (part.length() > 0) {
+                            parts.addElement(part);
+                        }
+                    }
+                    first = index+1;
+                }
+                index++;
+            }
+            // Reflow as XML
+            StringBuffer buf = new StringBuffer();
+            Object[] list = parts.toArray();
+            int indent = 0;
+            int pad = 0;
+            index = 0;
+            while (index < list.length) {
+                part = (String) list[index];
+                if (buf.length() == 0) {
+                    // Just add first tag (should be XML header)
+                    buf.append(part);
+                } else {
+                    // All other parts need to start on a new line
+                    buf.append('\n');
+                    // If we're at an end tag then decrease indent
+                    if (part.startsWith("</")) {
+                        indent--;
+                    }            
+                    // Add any indent
+                    for (pad = 0; pad < indent; pad++) {
+                        buf.append("  ");
+                    }
+                    // Add the tag or data
+                    buf.append(part);
+                    // If this is a start tag then increase indent
+                    if (part.startsWith("<") &&
+                        !part.startsWith("</") &&
+                        !part.endsWith("/>")) {
+                        indent++;
+                        // Check for special <tag>data</tag> case
+                        if ((index + 2) < list.length) {
+                            part = (String) list[index+2];
+                            if (part.startsWith("</")) {
+                                part = (String) list[index+1];
+                                if (!part.startsWith("<")) {
+                                    buf.append(part);
+                                    part = (String) list[index+2];
+                                    buf.append(part);
+                                    index = index + 2;
+                                    indent--;
+                                }
+                            }
+                        }
+                    }
+                }
+                index++;
+            }
+            formatted = new String(buf);
+        }
+    }
+}
diff --git a/webapps/axis/StockQuoteService.jws b/webapps/axis/StockQuoteService.jws
new file mode 100644
index 0000000..8a29a75
--- /dev/null
+++ b/webapps/axis/StockQuoteService.jws
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.axis.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * See \samples\stock\readme for info.
+ *
+ * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
+ * @author Doug Davis (dug@us.ibm.com)
+ */
+public class StockQuoteService {
+  public float getQuote (String symbol) throws Exception {
+    // get a real (delayed by 20min) stockquote from 
+    // http://www.xmltoday.com/examples/stockquote/. The IP addr 
+    // below came from the host that the above form posts to ..
+
+    if ( symbol.equals("XXX") ) return( (float) 66.25 );
+
+
+    Document doc = null ;
+    
+    doc = XMLUtils.newDocument( "http://www.xmltoday.com/examples/" +
+                                "stockquote/getxmlquote.vep?s="+symbol );
+
+    Element  elem = doc.getDocumentElement();
+    NodeList list = elem.getElementsByTagName("stock_quote");
+
+    elem = (Element) list.item(0);
+    list = elem.getElementsByTagName( "price" );
+    elem = (Element) list.item( 0 );
+    String quoteStr = elem.getAttribute("value");
+    try {
+      return Float.valueOf(quoteStr).floatValue();
+    } catch (NumberFormatException e1) {
+      // maybe its an int?
+      try {
+        return Integer.valueOf(quoteStr).intValue() * 1.0F;
+      } catch (NumberFormatException e2) {
+        return -1.0F;
+      }
+    }
+  }
+}
diff --git a/webapps/axis/WEB-INF/web.xml b/webapps/axis/WEB-INF/web.xml
new file mode 100644
index 0000000..67f1ef9
--- /dev/null
+++ b/webapps/axis/WEB-INF/web.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
+Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  <display-name>Apache-Axis</display-name>
+    
+    <listener>
+        <listener-class>org.apache.axis.transport.http.AxisHTTPSessionListener</listener-class>
+    </listener>
+    
+  <servlet>
+    <servlet-name>AxisServlet</servlet-name>
+    <display-name>Apache-Axis Servlet</display-name>
+    <servlet-class>
+        org.apache.axis.transport.http.AxisServlet
+    </servlet-class>
+  </servlet>
+
+  <servlet>
+    <servlet-name>AdminServlet</servlet-name>
+    <display-name>Axis Admin Servlet</display-name>
+    <servlet-class>
+        org.apache.axis.transport.http.AdminServlet
+    </servlet-class>
+    <load-on-startup>100</load-on-startup>
+  </servlet>
+
+  <servlet>
+    <servlet-name>SOAPMonitorService</servlet-name>
+    <display-name>SOAPMonitorService</display-name>
+    <servlet-class>
+        org.apache.axis.monitor.SOAPMonitorService
+    </servlet-class>
+    <init-param>
+      <param-name>SOAPMonitorPort</param-name>
+      <param-value>5001</param-value>
+    </init-param>
+    <load-on-startup>100</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>AxisServlet</servlet-name>
+    <url-pattern>/servlet/AxisServlet</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>AxisServlet</servlet-name>
+    <url-pattern>*.jws</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>AxisServlet</servlet-name>
+    <url-pattern>/services/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>SOAPMonitorService</servlet-name>
+    <url-pattern>/SOAPMonitor</url-pattern>
+  </servlet-mapping>
+
+ <!-- uncomment this if you want the admin servlet -->
+ <!--
+  <servlet-mapping>
+    <servlet-name>AdminServlet</servlet-name>
+    <url-pattern>/servlet/AdminServlet</url-pattern>
+  </servlet-mapping>
+ -->
+
+    <session-config>
+        <!-- Default to 5 minute session timeouts -->
+        <session-timeout>5</session-timeout>
+    </session-config>
+
+    <!-- currently the W3C havent settled on a media type for WSDL;
+    http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft
+    for now we go with the basic 'it's XML' response -->
+  <mime-mapping>
+    <extension>wsdl</extension>
+     <mime-type>text/xml</mime-type>
+  </mime-mapping>
+  
+
+  <mime-mapping>
+    <extension>xsd</extension>
+    <mime-type>text/xml</mime-type>
+  </mime-mapping>
+
+  <welcome-file-list id="WelcomeFileList">
+    <welcome-file>index.html</welcome-file>
+    <welcome-file>index.jsp</welcome-file>
+    <welcome-file>index.jws</welcome-file>
+  </welcome-file-list>
+
+</web-app>
diff --git a/webapps/axis/fingerprint.jsp b/webapps/axis/fingerprint.jsp
new file mode 100644
index 0000000..644359e
--- /dev/null
+++ b/webapps/axis/fingerprint.jsp
@@ -0,0 +1,272 @@
+<%@ page import="java.io.File,
+                 java.io.IOException,
+                 java.util.Date"
+    session="false" %>
+<html>
+<head>
+<title>System Fingerprint</title>
+</head>
+<body bgcolor=#ffffff>
+<%!
+
+    /*
+     * Fingerprint the users system. This is mainly for use in
+     * diagnosing classpath problems. It is intended to dump out
+     * a copy of the environment this webapp is running in,
+     * and additionally attempt to identify versions of each jar
+     * in the classpath.
+     *
+     * @author Brian Ewins
+     */
+
+    private java.util.Properties versionProps=new java.util.Properties();
+
+    /**
+     * Identify the version of a jar file. This uses a properties file
+     * containing known names and sizes in the format
+     * 'name(size)=version'. Version strings should be like 'xerces-1.4'
+     * ie they should include the name of the library.
+     */
+    public String getFileVersion(File file) throws IOException {
+        String key="<td>"+file.getName()+"</td>";
+        key+= "<td>"+file.length()+"</td>";
+        Date timestamp=new Date(file.lastModified());
+        key+= "<td>"+timestamp.toString()+"</td>";
+        return key;
+
+        /* TODO: implement
+        String value=versionProps.getProperty(key);
+        if (value==null) {
+            // make it possible to have jars without version nos
+            value=versionProps.getProperty(file.getName());
+        }
+        if (value==null) {
+            // fall back on something obvious
+            value=key;
+            Date timestamp=new Date(file.lastModified());
+            value+=" / "+timestamp.toString();
+        }
+        return value;
+        */
+    }
+
+    /**
+     * Split up a classpath-like variable. Returns a list of files.
+     * TODO: this can't cope with relative paths. I think theres code in BCEL that
+     * can be used for this?
+     */
+    File[] splitClasspath(String path) throws IOException {
+        java.util.StringTokenizer st=
+            new java.util.StringTokenizer(path,
+                            System.getProperty("path.separator"));
+        int toks=st.countTokens();
+        File[] files=new File[toks];
+        for(int i=0;i<toks;i++) {
+            files[i]=new File(st.nextToken());
+        }
+        return files;
+    }
+
+    /** given a list of files, return a list of jars which actually exist */
+    File[] scanFiles(File[] files) throws IOException {
+        File[] jars=new File[files.length];
+        int found=0;
+        for (int i=0; i<files.length; i++) {
+            if (files[i].getName().toLowerCase().endsWith(".jar")
+                    && files[i].exists()) {
+                jars[found]=files[i];
+                found++;
+            }
+        }
+        if (found<files.length) {
+            File[] temp=new File[found];
+            System.arraycopy(jars,0,temp,0,found);
+            jars=temp;
+        }
+        return jars;    
+    }
+
+    private static final File[] NO_FILES=new File[0];
+
+    /** scan a directory for jars */    
+    public File[] scanDir(String dir) throws IOException 
+        {
+        if(dir==null) {
+            return NO_FILES;
+        }
+        return scanDir(new File(dir));
+        }
+        
+    public File[] scanDir(File dir) throws IOException {
+        if (!dir.exists() || !dir.isDirectory()) {
+            return NO_FILES;
+        }
+        return scanFiles(dir.listFiles());
+    }
+
+    /** scan a classpath for jars */    
+    public File[] scanClasspath(String path) throws IOException {
+        if (path==null) {
+            return NO_FILES;
+        }
+        return scanFiles(splitClasspath(path));
+    }
+
+    /** 
+     * scan a 'dirpath' (like the java.ext.dirs system property) for jars 
+     */   
+    public File[] scanDirpath(String path) throws IOException {
+        if (path==null) {
+            return NO_FILES;
+        }
+        File[] current=new File[0];
+        File[] dirs=splitClasspath(path);
+        for(int i=0; i<dirs.length; i++) {
+            File[] jars=scanDir(dirs[i]);
+            File[] temp=new File[current.length+jars.length];
+            System.arraycopy(current,0,temp,0,current.length);
+            System.arraycopy(jars,0,temp,current.length,jars.length);
+            current=temp;
+        }
+        return scanFiles(current);
+    }
+
+    /** print out the jar versions for a directory */
+    public void listDirectory(String title, JspWriter out,String dir, String comment) throws IOException {
+        listVersions(title, out,scanDir(dir), comment);
+    }
+
+    /** print out the jar versions for a directory-like system property */
+    public void listDirProperty(String title, JspWriter out,String key, String comment) throws IOException {
+        listVersions(title, out,scanDir(System.getProperty(key)), comment);
+    }
+
+    /** print out the jar versions for a classpath-like system property */
+    public void listClasspathProperty(String title, JspWriter out,String key, String comment) throws IOException {
+        listVersions(title, out,scanClasspath(System.getProperty(key)), comment);
+    }
+
+    /** print out the jar versions for a 'java.ext.dirs'-like system property */
+    public void listDirpathProperty(String title, JspWriter out,String key, String comment) throws IOException {
+        listVersions(title, out,scanDirpath(System.getProperty(key)), comment);
+    }
+
+    /** print out the jar versions for a context-relative directory */
+    public void listContextPath(String title, JspWriter out, String path, String comment)  throws IOException {
+        listVersions(title, out,scanDir(getServletConfig().getServletContext().getRealPath(path)), comment);
+    }
+
+    /** print out the jar versions for a given list of files */
+    public void listVersions(String title, JspWriter out,File[] jars, String comment) throws IOException {
+        out.print("<h2>");
+        out.print(title);
+        out.println("</h2>");
+        out.println("<table>");
+        for (int i=0; i<jars.length; i++) {
+            out.println("<tr>"+getFileVersion(jars[i])+"</tr>");
+        }
+        out.println("</table>");
+        if(comment!=null && comment.length()>0) {
+            out.println("<p>");
+            out.println(comment);
+            out.println("<p>");
+        }
+    }
+
+%>
+<h1>System Fingerprint</h1>
+<h2>JVM and Server Version</h2>
+<table>
+<tr>
+    <td>Servlet Engine</td>
+    <td><%= getServletConfig().getServletContext().getServerInfo() %></td>
+    <td><%= getServletConfig().getServletContext().getMajorVersion() %></td>
+    <td><%= getServletConfig().getServletContext().getMinorVersion() %></td>
+</tr>
+<tr>
+    <td>Java VM</td>
+    <td><%= System.getProperty("java.vm.vendor") %></td>
+    <td><%= System.getProperty("java.vm.name") %></td>
+    <td><%= System.getProperty("java.vm.version") %></td>
+</tr>
+<tr>
+    <td>Java RE</td>
+    <td><%= System.getProperty("java.vendor") %></td>
+    <td><%= System.getProperty("java.version") %></td>
+    <td> </td>
+</tr>
+<tr>
+    <td>Platform</td>
+    <td><%= System.getProperty("os.name") %></td>
+    <td><%= System.getProperty("os.arch") %></td>
+    <td><%= System.getProperty("os.version") %></td>
+</tr>
+</table>
+
+<%
+listClasspathProperty("Boot jars", out,"sun.boot.class.path", "Only valid on a sun jvm");
+listClasspathProperty("System jars", out,"java.class.path", null);
+listDirpathProperty("Extra system jars", out,"java.ext.dirs", null);
+listContextPath("Webapp jars", out, "/WEB-INF/lib", null);
+// identify the container...
+String container=getServletConfig().getServletContext().getServerInfo();
+if (container.startsWith("Tomcat Web Server/3.2")) {
+    String home=System.getProperty("tomcat.home");
+    if(home!=null) {
+        listDirectory("Tomcat 3.2 Common Jars", out,
+                      home+File.separator
+                      +"lib",
+                      null);
+    }
+} else if (container.startsWith("Tomcat Web Server/3.3")) {
+    String home=System.getProperty("tomcat.home");
+    if(home!=null) {
+        listDirectory("Tomcat 3.3 Container Jars", out,
+                      home+File.separator
+                      +"lib"+File.separator
+                      +"container",
+                      null);
+        listDirectory("Tomcat 3.3 Common Jars", out,
+                      home+File.separator
+                      +"lib"+File.separator
+                      +"common",
+                      null);
+    }
+} else if (container.startsWith("Apache Tomcat/4.0")) {
+    //handle catalina common dir
+    String home=System.getProperty("catalina.home");
+    if(home!=null) {
+        listDirectory("Tomcat 4.0 Common Jars", out,
+                      home+File.separator
+                      +"common"+File.separator
+                      +"lib",
+                      null);
+    }
+} else if (container.startsWith("Apache Tomcat/4.1")) {
+    //handle catalina common dir
+    String home=System.getProperty("catalina.home");
+    if(home!=null) {
+        listDirectory("Tomcat 4.1 Common Jars", out,
+                      home+File.separator
+                      +"shared"+File.separator
+                      +"lib",
+                      null);
+    }
+} else if (System.getProperty("resin.home")!=null) {
+    String home=System.getProperty("resin.home");
+    if(home!=null) {
+        listDirectory("Resin Common Jars", out,
+                      home+File.separator
+                      +"lib",
+                      null);
+    }    
+} else if (System.getProperty("weblogic.httpd.servlet.classpath")!=null) {
+    listClasspathProperty("Weblogic Servlet Jars", out,
+                  "weblogic.httpd.servlet.classpath",
+                  null);
+} else {
+    //TODO: identify more servlet engine classpaths.
+}
+%>
+</body>
+</html>
\ No newline at end of file
diff --git a/webapps/axis/happyaxis.jsp b/webapps/axis/happyaxis.jsp
new file mode 100644
index 0000000..4133423
--- /dev/null
+++ b/webapps/axis/happyaxis.jsp
@@ -0,0 +1,488 @@
+<html>
+<%@ page import="java.io.InputStream,
+                 java.io.IOException,
+                 javax.xml.parsers.SAXParser,
+                 javax.xml.parsers.SAXParserFactory"
+   session="false" %>
+ <%
+    /*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+%>
+<head>
+<title>Axis Happiness Page</title>
+</head>
+<body bgcolor='#ffffff'>
+<%!
+
+    /*
+     * Happiness tests for axis. These look at the classpath and warn if things
+     * are missing. Normally addng this much code in a JSP page is mad
+     * but here we want to validate JSP compilation too, and have a drop-in
+     * page for easy re-use
+     * @author Steve 'configuration problems' Loughran
+     * @author dims
+     * @author Brian Ewins
+     */
+
+
+    /**
+     * Get a string providing install information.
+     * TODO: make this platform aware and give specific hints
+     */
+    public String getInstallHints(HttpServletRequest request) {
+
+        String hint=
+            "<B><I>Note:</I></B> On Tomcat 4.x and Java1.4, you may need to put libraries that contain "
+            +"java.* or javax.* packages into CATALINA_HOME/common/lib"
+            +"<br>jaxrpc.jar and saaj.jar are two such libraries.";
+        return hint;
+    }
+
+    /**
+     * test for a class existing
+     * @param classname
+     * @return class iff present
+     */
+    Class classExists(String classname) {
+        try {
+            return Class.forName(classname);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * test for resource on the classpath
+     * @param resource
+     * @return true iff present
+     */
+    boolean resourceExists(String resource) {
+        boolean found;
+        InputStream instream=this.getClass().getResourceAsStream(resource);
+        found=instream!=null;
+        if(instream!=null) {
+            try {
+                instream.close();
+            } catch (IOException e) {
+            }
+        }
+        return found;
+    }
+
+    /**
+     * probe for a class, print an error message is missing
+     * @param out stream to print stuff
+     * @param category text like "warning" or "error"
+     * @param classname class to look for
+     * @param jarFile where this class comes from
+     * @param errorText extra error text
+     * @param homePage where to d/l the library
+     * @return the number of missing classes
+     * @throws IOException
+     */
+    int probeClass(JspWriter out,
+                   String category,
+                   String classname,
+                   String jarFile,
+                   String description,
+                   String errorText,
+                   String homePage) throws IOException {
+        try {
+            Class clazz = classExists(classname);
+            if(clazz == null)  {
+               String url="";
+               if(homePage!=null) {
+                  url="<br>  See <a href="+homePage+">"+homePage+"</a>";
+               }
+               out.write("<p>"+category+": could not find class "+classname
+                   +" from file <b>"+jarFile
+                   +"</b><br>  "+errorText
+                   +url
+                   +"<p>");
+               return 1;
+            } else {
+               String location = getLocation(out, clazz);
+               if(location == null) {
+                  out.write("Found "+ description + " (" + classname + ")<br>");
+               }
+               else {
+                  out.write("Found "+ description + " (" + classname + ") at " + location + "<br>");
+               }
+               return 0;
+            }
+        } catch(NoClassDefFoundError ncdfe) { 
+            String url="";
+            if(homePage!=null) {
+                url="<br>  See <a href="+homePage+">"+homePage+"</a>";
+            }
+            out.write("<p>"+category+": could not find a dependency"
+                    +" of class "+classname
+                    +" from file <b>"+jarFile
+                    +"</b><br> "+errorText
+                    +url
+                    +"<br>The root cause was: "+ncdfe.getMessage()
+                    +"<br>This can happen e.g. if "+classname+" is in" 
+                    +" the 'common' classpath, but a dependency like "
+                    +" activation.jar is only in the webapp classpath."
+                    +"<p>");
+            return 1;
+        }
+    }
+
+    /**
+     * get the location of a class
+     * @param out
+     * @param clazz
+     * @return the jar file or path where a class was found
+     */
+
+    String getLocation(JspWriter out,
+                       Class clazz) {
+        try {
+            java.net.URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
+            String location = url.toString();
+            if(location.startsWith("jar")) {
+                url = ((java.net.JarURLConnection)url.openConnection()).getJarFileURL();
+                location = url.toString();
+            } 
+            
+            if(location.startsWith("file")) {
+                java.io.File file = new java.io.File(url.getFile());
+                return file.getAbsolutePath();
+            } else {
+                return url.toString();
+            }
+        } catch (Throwable t){
+        }
+        return "an unknown location";
+    }
+
+    /**
+     * a class we need if a class is missing
+     * @param out stream to print stuff
+     * @param classname class to look for
+     * @param jarFile where this class comes from
+     * @param errorText extra error text
+     * @param homePage where to d/l the library
+     * @throws IOException when needed
+     * @return the number of missing libraries (0 or 1)
+     */
+    int needClass(JspWriter out,
+                   String classname,
+                   String jarFile,
+                   String description,
+                   String errorText,
+                   String homePage) throws IOException {
+        return probeClass(out,
+                "<b>Error</b>",
+                classname,
+                jarFile,
+                description,
+                errorText,
+                homePage);
+    }
+
+    /**
+     * print warning message if a class is missing
+     * @param out stream to print stuff
+     * @param classname class to look for
+     * @param jarFile where this class comes from
+     * @param errorText extra error text
+     * @param homePage where to d/l the library
+     * @throws IOException when needed
+     * @return the number of missing libraries (0 or 1)
+     */
+    int wantClass(JspWriter out,
+                   String classname,
+                   String jarFile,
+                   String description,
+                   String errorText,
+                   String homePage) throws IOException {
+        return probeClass(out,
+                "<b>Warning</b>",
+                classname,
+                jarFile,
+                description,
+                errorText,
+                homePage);
+    }
+
+    /**
+     * probe for a resource existing,
+     * @param out
+     * @param resource
+     * @param errorText
+     * @throws Exception
+     */
+    int wantResource(JspWriter out,
+                      String resource,
+                      String errorText) throws Exception {
+        if(!resourceExists(resource)) {
+            out.write("<p><b>Warning</b>: could not find resource "+resource
+                        +"<br>"
+                        +errorText);
+            return 0;
+        } else {
+            out.write("found "+resource+"<br>");
+            return 1;
+        }
+    }
+
+
+    /**
+     *  get servlet version string
+     *
+     */
+
+    public String getServletVersion() {
+        ServletContext context=getServletConfig().getServletContext();
+        int major = context.getMajorVersion();
+        int minor = context.getMinorVersion();
+        return Integer.toString(major) + '.' + Integer.toString(minor);
+    }
+
+
+
+    /**
+     * what parser are we using.
+     * @return the classname of the parser
+     */
+    private String getParserName() {
+        SAXParser saxParser = getSAXParser();
+        if (saxParser == null) {
+            return "Could not create an XML Parser";
+        }
+
+        // check to what is in the classname
+        String saxParserName = saxParser.getClass().getName();
+        return saxParserName;
+    }
+
+    /**
+     * Create a JAXP SAXParser
+     * @return parser or null for trouble
+     */
+    private SAXParser getSAXParser() {
+        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+        if (saxParserFactory == null) {
+            return null;
+        }
+        SAXParser saxParser = null;
+        try {
+            saxParser = saxParserFactory.newSAXParser();
+        } catch (Exception e) {
+        }
+        return saxParser;
+    }
+
+    /**
+     * get the location of the parser
+     * @return path or null for trouble in tracking it down
+     */
+
+    private String getParserLocation(JspWriter out) {
+        SAXParser saxParser = getSAXParser();
+        if (saxParser == null) {
+            return null;
+        }
+        String location = getLocation(out,saxParser.getClass());
+        return location;
+    }
+    %>
+<html><head><title>Axis Happiness Page</title></head>
+<body>
+<h1>Axis Happiness Page</h1>
+<h2>Examining webapp configuration</h2>
+
+<p>
+<h3>Needed Components</h3>
+<%
+    int needed=0,wanted=0;
+
+    /**
+     * the essentials, without these Axis is not going to work
+     */
+    needed=needClass(out, "javax.xml.soap.SOAPMessage",
+            "saaj.jar",
+            "SAAJ API",
+            "Axis will not work",
+            "http://xml.apache.org/axis/");
+
+    needed+=needClass(out, "javax.xml.rpc.Service",
+            "jaxrpc.jar",
+            "JAX-RPC API",
+            "Axis will not work",
+            "http://xml.apache.org/axis/");
+
+    needed+=needClass(out, "org.apache.axis.transport.http.AxisServlet",
+            "axis.jar",
+            "Apache-Axis",
+            "Axis will not work",
+            "http://xml.apache.org/axis/");
+
+    needed+=needClass(out, "org.apache.commons.discovery.Resource",
+            "commons-discovery.jar",
+            "Jakarta-Commons Discovery",
+            "Axis will not work",
+            "http://jakarta.apache.org/commons/discovery.html");
+
+    needed+=needClass(out, "org.apache.commons.logging.Log",
+            "commons-logging.jar",
+            "Jakarta-Commons Logging",
+            "Axis will not work",
+            "http://jakarta.apache.org/commons/logging.html");
+
+    needed+=needClass(out, "org.apache.log4j.Layout",
+            "log4j-1.2.8.jar",
+            "Log4j",
+            "Axis may not work",
+            "http://jakarta.apache.org/log4j");
+
+    //should we search for a javax.wsdl file here, to hint that it needs
+    //to go into an approved directory? because we dont seem to need to do that.
+    needed+=needClass(out, "com.ibm.wsdl.factory.WSDLFactoryImpl",
+            "wsdl4j.jar",
+            "IBM's WSDL4Java",
+            "Axis will not work",
+            null);
+
+    needed+=needClass(out, "javax.xml.parsers.SAXParserFactory",
+            "xerces.jar",
+            "JAXP implementation",
+            "Axis will not work",
+            "http://xml.apache.org/xerces-j/");
+
+    needed+=needClass(out,"javax.activation.DataHandler",
+            "activation.jar",
+            "Activation API",
+            "Axis will not work",
+            "http://java.sun.com/products/javabeans/glasgow/jaf.html");
+%>
+<h3>Optional Components</h3>
+<%
+    /*
+     * now the stuff we can live without
+     */
+    wanted+=wantClass(out,"javax.mail.internet.MimeMessage",
+            "mail.jar",
+            "Mail API",
+            "Attachments will not work",
+            "http://java.sun.com/products/javamail/");
+
+    wanted+=wantClass(out,"org.apache.xml.security.Init",
+            "xmlsec.jar",
+            "XML Security API",
+            "XML Security is not supported",
+            "http://xml.apache.org/security/");
+
+    wanted += wantClass(out, "javax.net.ssl.SSLSocketFactory",
+            "jsse.jar or java1.4+ runtime",
+            "Java Secure Socket Extension",
+            "https is not supported",
+            "http://java.sun.com/products/jsse/");
+    /*
+     * resources on the classpath path
+     */
+    /* broken; this is a file, not a resource
+    wantResource(out,"/server-config.wsdd",
+            "There is no server configuration file;"
+            +"run AdminClient to create one");
+    */
+    /* add more libraries here */
+
+    out.write("<h3>");
+    //is everythng we need here
+    if(needed==0) {
+       //yes, be happy
+        out.write("<i>The core axis libraries are present. </i>");
+    } else {
+        //no, be very unhappy
+        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        out.write("<i>"
+                +needed
+                +" core axis librar"
+                +(needed==1?"y is":"ies are")
+                +" missing</i>");
+    }
+    //now look at wanted stuff
+    if(wanted>0) {
+        out.write("<i>"
+                +wanted
+                +" optional axis librar"
+                +(wanted==1?"y is":"ies are")
+                +" missing</i>");
+    } else {
+        out.write("The optional components are present.");
+    }
+    out.write("</h3>");
+    //hint if anything is missing
+    if(needed>0 || wanted>0 ) {
+        out.write(getInstallHints(request));
+    }
+
+    %>
+    <p>
+    <B><I>Note:</I></B> Even if everything this page probes for is present, there is no guarantee your
+    web service will work, because there are many configuration options that we do
+    not check for. These tests are <i>necessary</i> but not <i>sufficient</i>
+    <hr>
+
+    <h2>Examining Application Server</h2>
+    <%
+        String servletVersion=getServletVersion();
+        String xmlParser=getParserName();
+        String xmlParserLocation = getParserLocation(out);
+
+    %>
+    <table>
+        <tr><td>Servlet version</td><td><%= servletVersion %></td></tr>
+        <tr><td>XML Parser</td><td><%= xmlParser %></td></tr>
+        <tr><td>XML ParserLocation</td><td><%= xmlParserLocation %></td></tr>
+    </table>
+<% if(xmlParser.indexOf("crimson")>=0) { %>
+    <p>
+    <b>We recommend <a href="http://xml.apache.org/xerces2-j/">Xerces 2</a>
+        over Crimson as the XML parser for Axis</b>
+    </p>
+<%    } %>
+
+    <h2>Examining System Properties</h2>
+<%
+    /** 
+     * Dump the system properties
+     */
+    java.util.Enumeration e=null;
+    try {
+        e= System.getProperties().propertyNames();
+    } catch (SecurityException se) {
+    }
+    if(e!=null) {
+        out.write("<pre>");
+        for (;e.hasMoreElements();) {
+            String key = (String) e.nextElement();
+            out.write(key + "=" + System.getProperty(key)+"\n");
+        }
+        out.write("</pre><p>");
+    } else {
+        out.write("System properties are not accessible<p>");
+    }
+%>
+    <hr>
+    Platform: <%= getServletConfig().getServletContext().getServerInfo()  %>
+</body>
+</html>
+
+
diff --git a/webapps/axis/index.html b/webapps/axis/index.html
new file mode 100644
index 0000000..30abc39
--- /dev/null
+++ b/webapps/axis/index.html
@@ -0,0 +1,48 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>Apache-Axis</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h1 align="center">Apache-AXIS</h1>
+
+<p>Hello! <em>Welcome</em> to Apache-Axis.</p>
+
+<p>What do you want to do today?</p>
+
+<ul>
+    <li><a href="happyaxis.jsp">Validate</a>
+        the local installation's configuration<br>
+        <i>see below if this does not work.</i></li>
+    <li><a href="servlet/AxisServlet">View</a>
+        the list of deployed Web services</li>
+    <li><a href="EchoHeaders.jws?method=list">
+        Call a local endpoint</a> that list's the caller's
+        http headers (or see its
+        <a href="EchoHeaders.jws?wsdl">WSDL</a>). 
+    <li><a href="http://xml.apache.org/axis">Visit</a>
+        the Apache-Axis Home Page</li>
+    <li><a href="servlet/AdminServlet">Administer Axis</a> <br>
+        [disabled by default for security reasons]</li>
+    <li><a href="SOAPMonitor">SOAPMonitor</a> <br>
+        [disabled by default for security reasons]</li>
+</ul>
+To enable the disabled features, uncomment the appropriate declarations in 
+WEB-INF/web.xml in the webapplication and restart it.
+<h3>Validating Axis</h3>
+
+If the "happyaxis" validation page displays an exception instead of a 
+status page, the likely cause is that you have multiple XML parsers in 
+your classpath. Clean up your classpath by eliminating extraneous parsers. 
+
+<p>
+If you have problems getting Axis to work, consult the Axis 
+<a
+href="http://nagoya.apache.org/wiki/apachewiki.cgi?AxisProjectPages">Wiki</a>
+and then try the Axis user mailing list. 
+</body>
+</html>
diff --git a/webapps/axis/interop.jsp b/webapps/axis/interop.jsp
new file mode 100644
index 0000000..88bc26c
--- /dev/null
+++ b/webapps/axis/interop.jsp
@@ -0,0 +1,58 @@
+<html>

+<%@ page language="java" import="org.apache.ws.axis.oasis.ping.*, javax.xml.rpc.holders.StringHolder" %>

+

+<% 

+	String context = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/services" ;

+%>

+<head><title>WSS4J Interop Client</title></head>

+<body>

+<big><strong>WSS4J Interop Client</strong></big><p>

+If you have problems using this self-help page. Please send an email to <A href="mailto:dims@yahoo.com">Davanum Srinivas</a>

+<p/>

+<dl>

+<dt><strong>Interop Scenario 1</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="1">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping1' /></td></tr>

+

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 1'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 2</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="2">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping2' /></td></tr>

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 2'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 3</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="3">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping3' /></td></tr>

+

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 3'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 4</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="4">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping4' /></td></tr>

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 4'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 5</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="5">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping5' /></td></tr>

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 5'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 6</strong></dt>

+

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="6">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping6' /></td></tr>

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 6'></td></tr>

+</form></table></dd>

+<dt><strong>Interop Scenario 7</strong></dt>

+<dd><table border='0'><form method='POST' action='wss4j2.jsp'><INPUT NAME="scenario" TYPE=HIDDEN VALUE="7">

+<tr><td colspan='2'>URL: <input type='text' size='64' name='url' value='<%= context %>/Ping7' /></td></tr>

+<tr><td>&nbsp;</td><td align='right'><input type='submit' value='Interop 7'></td></tr>

+</form></table></dd>

+</dl>

+<p/>        <font size="-1">

+

+         <em>Copyright &#169; 1999-2004, The Apache Software Foundation</em>

+        </font>

+

+</body>

+</html>
\ No newline at end of file
diff --git a/webapps/axis/wss4j2.jsp b/webapps/axis/wss4j2.jsp
new file mode 100644
index 0000000..8ab3dbd
--- /dev/null
+++ b/webapps/axis/wss4j2.jsp
@@ -0,0 +1,56 @@
+<html>
+<%@ page language="java" import="org.apache.ws.axis.oasis.ping.*, javax.xml.rpc.holders.StringHolder" %>
+
+<% 
+	String url = request.getParameter ("url");
+	String scenario = request.getParameter ("scenario").trim();
+%>
+<head><title>WSS4J Interop Scenario <%= scenario %> Results</title></head>
+<body>
+<big><strong>WSS4J Interop Scenario <%= scenario %> Results</strong></big><p>
+<strong>Server URL:</strong> <%= url %><p>
+
+<%
+        PingServiceLocator service = new PingServiceLocator();
+        java.net.URL endpoint = new java.net.URL(url);
+        PingPort port = null;
+        if(scenario.equals("1"))
+             port = (PingPort) service.getPing1(endpoint);
+        else if(scenario.equals("2"))
+             port = (PingPort) service.getPing2(endpoint);
+        else if(scenario.equals("3"))
+             port = (PingPort) service.getPing3(endpoint);
+        else if(scenario.equals("4"))
+             port = (PingPort) service.getPing4(endpoint);
+        else if(scenario.equals("5"))
+             port = (PingPort) service.getPing5(endpoint);
+        else if(scenario.equals("6"))
+             port = (PingPort) service.getPing6(endpoint);
+        else if(scenario.equals("7"))
+             port = (PingPort) service.getPing7(endpoint);
+
+        StringHolder text =
+                new StringHolder("WSS4J - Scenario " + scenario + " @ [" + new java.util.Date(System.currentTimeMillis()) + "]");
+%>
+<strong>Request:</strong> <%= text.value %><p>
+
+<%
+
+        port.ping(new org.apache.ws.axis.oasis.ping.TicketType("WSS4J" + scenario), text);
+        System.out.println(text.value);
+
+%>
+<strong>Response:</strong> <%= text.value %><p>
+
+<p/>
+<font size="-1">
+<A HREF="wss4j.html">Go Back</A>
+</font>
+<p/>        <font size="-1">
+
+         <em>Copyright &#169; 1999-2004, The Apache Software Foundation</em>
+        </font>
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/wss4j-readme.html b/wss4j-readme.html
new file mode 100644
index 0000000..40df2bb
--- /dev/null
+++ b/wss4j-readme.html
@@ -0,0 +1,201 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+	<TITLE>Apache WSS4J-1.5.0</TITLE>
+	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.9.79  (Linux)">
+	<META NAME="AUTHOR" CONTENT="Werner Dittmann">
+	<META NAME="CREATED" CONTENT="20050904;11070500">
+	<META NAME="CHANGEDBY" CONTENT="Werner Dittmann">
+	<META NAME="CHANGED" CONTENT="20050904;12155500">
+	<STYLE>
+	<!--
+		@page { size: 21cm 29.7cm }
+		H1.western { font-family: "Times New Roman" }
+	-->
+	</STYLE>
+</HEAD>
+<BODY LANG="de-DE" DIR="LTR">
+<H1 CLASS="western">What is WSS4J?</H1>
+<P STYLE="margin-bottom: 0cm">WSS4J is part of the Apache Web
+Services project. Here is <A HREF="http://ws.apache.org/">link </A>the
+to all Apache Web Service projects.</P>
+<P STYLE="margin-bottom: 0cm">Apache WSS4J is an implementation of
+the OASIS Web Services Security specifications (WS-Security, WSS)
+from OASIS Web Services Security TC. WSS4J is primarily a Java
+library that can be used to sign, verify, encrypt, and decrypt SOAP
+Messages according to the WS-Security specifications. WSS4J uses
+Apache Axis and other Apache XML-Security projects and is
+interoperable with other JAX-RPC based server/clients and .Net WSE
+server/clients that follow the OASIS WSS specifications.</P>
+<H2>Supported WSS Specifications</H2>
+<P STYLE="margin-bottom: 0cm">WSS4J implements</P>
+<UL>
+	<LI><P STYLE="margin-bottom: 0cm">OASIS Web Serives Security: SOAP
+	Message Security 1.0 Standard 200401, March 2004</P>
+	<LI><P STYLE="margin-bottom: 0cm">Username Token profile V1.0</P>
+	<LI><P STYLE="margin-bottom: 0cm">X.509 Token Profile V1.0</P>
+</UL>
+<P STYLE="margin-bottom: 0cm">The Web Services Security part of WSS4J
+is fairly well tested and many WebService projects use it already.
+Also interoperability with various other implementations is well
+tested.</P>
+<H2>Support of older WSS specifications</H2>
+<P STYLE="margin-bottom: 0cm">The WSS4J release 1.1.0 is the last release 
+that was able to emulate previous WSS specs.
+</P>
+<P STYLE="margin-bottom: 0cm">This and  next WSS4J releases (&gt;= 1.5.x)</P>
+<UL>
+	<LI><P STYLE="margin-bottom: 0cm">support the OASIS V1.0 specs and
+	the relevant namespaces only</P>
+	<LI><P STYLE="margin-bottom: 0cm">support one versions of
+	provisional (draft) namespaces for the upcoming version</P>
+</UL>
+<P STYLE="margin-bottom: 0cm">After the next version of the WSS specs
+is finished, we do one WSS4J release with the provisional namespaces
+and another release (with a new release number) with the then fixed
+namespace URIs. Doing so we could save a lot of coding while
+retaining some backward compatibility using the n-1 release.</P>
+<H2>Web Services Security Features 
+</H2>
+<P STYLE="margin-bottom: 0cm">WSS4J can generate and process the
+following SOAP Bindings:</P>
+<UL>
+	<LI><P STYLE="margin-bottom: 0cm">XML Security</P>
+</UL>
+<UL>
+	<LI><P STYLE="margin-bottom: 0cm">XML Signature</P>
+	<LI><P STYLE="margin-bottom: 0cm">XML Encryption</P>
+	<LI><P STYLE="margin-bottom: 0cm">Tokens</P>
+	<LI><P STYLE="margin-bottom: 0cm">Username Tokens</P>
+	<LI><P STYLE="margin-bottom: 0cm">Timestamps</P>
+	<LI><P STYLE="margin-bottom: 0cm">SAML Tokens</P>
+</UL>
+<P STYLE="margin-right: 0.03cm; margin-bottom: 0cm">WSS4J supports
+X.509 binary certificates and certificate paths. Here is the <A HREF="http://ws.apache.org/wss4j/">link</A>
+to WSS4J. There is also a Wiki concering Apache WS projects and WSS4J
+as one of the WS sub-projects:</P>
+<P STYLE="margin-bottom: 0cm"><A HREF="http://wiki.apache.org/ws/">http://wiki.apache.org/ws/</A></P>
+<P STYLE="margin-bottom: 0cm"><A HREF="http://wiki.apache.org/ws/FrontPage/WsFx">http://wiki.apache.org/ws/FrontPage/WsFx</A></P>
+<H3>WS-Trust and WS-Secure Conversation specifications</H3>
+
+<p>WSS4J now comes with the support for derived key token signature and 
+encryption. This is used by the Axis2-"rahas" module to provide the 
+WS-Secure Conversation.</p>
+
+<p>WS-Trust support is also being developed within Axis2 based on WSS4J</p>
+
+<p><i>org.apache.ws.sandbox.</i> package contains experimental implementations of these 
+specifications.</p>
+
+<H2>Installation (binary distribution)</H2>
+<P STYLE="margin-bottom: 0cm">The WSS4J zip archive is the binary
+distribution and contains the wss4j jar file, some examples, test
+classes (incl. sources), the interop test classes (incl. sources and
+necessary certificate store), and the according client and server
+deployment and protery files.</P>
+<P STYLE="margin-bottom: 0cm">The WSS4J jar file contains all classes
+that implement the basic functions and the handlers. To install it
+make sure this jar file is in the classpath of your Axis client
+and/or Axis server. 
+</P>
+<P STYLE="margin-bottom: 0cm">In addition you need to set up the
+property files that contain information about the certificate
+keystores you use. The property files and the keystore are accessed
+either as resources via classpath or, if that fails, as files using
+the relative path of the application 
+</P>
+<P STYLE="margin-bottom: 0cm">Thus no specific installation is
+required. The wss4j-1.5.0.jar file should be included into ear or war files
+of enterprise or web application servers.</P>
+<P STYLE="margin-bottom: 0cm">Please refer to the JAVADOC files of
+the distribution for further information how to use WSS4J, the
+handlers, and how to setup the deployment files.</P>
+<H2>Required software</H2>
+<P STYLE="margin-bottom: 0cm">To work with WSS4J you need additional
+software. Most of the software is also needed by your SOAP base
+system, e.g. Apache Axis. 
+</P>
+<P STYLE="margin-bottom: 0cm">To simplify installation and operation
+of WSS4J an additional ZIP file is provided that holds all other JARs
+that are required by WSS4J. Please note that we probably not use the
+very latest versions of these JARs, but we used them during the
+tests.</P>
+<P STYLE="margin-bottom: 0cm"><B>NOTE</B>: If you use another XML
+parser than what is defined below (Xerces) make sure that your parser
+fully supports namespaces. The Crimson parser included in the Sun JDK
+1.4.x does not support namespaces or has a buggy implementation.</P>
+<P STYLE="margin-bottom: 0cm">To implement the Web Service Security
+(WSS) part specific software is required:</P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>addressing-1.0.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">This jar contains the
+implementation of WS-Adressing, required by WSS4J Trust (in sandbox).</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://ws.apache.org/addressing/">http://ws.apache.org/addressing/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>axis-1.4.jar<BR>axis-ant-1.4.jar<BR>axis-jaxrpc-1.4.jar<BR>axis-saaj-1.4.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">These jars contain
+the Apache Axis base software. They implement the basic SOAP
+processing, deployment, WSDL to Java, Java to WSDL tools and a lot
+more. Plase refer to a Axis documentation how to setup Axis. You
+should be familiar with Axis, its setup, and deployment methods
+before you start with any WSS4J functions.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://ws.apache.org/axis/">http://ws.apache.org/axis/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>bcprov-jdk13-132.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">This is the
+BouncyCastle library that implements all necessary encryption,
+hashing, certifcate, and keystore functions. Without this fanatstic
+library WSS4J wouldn't work at all.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://www.bouncycastle.org/">http://www.bouncycastle.org/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>commons-codec-1.3.jar<BR>commons-discovery-0.2.jar<BR>commons-httpclient-3.0-rc2.jar<BR>commons-logging-1.0.4.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">These jars are from
+the Commons project and provide may useful funtions, such as Base64
+encoding/decoding, resource lookup, and much more. Please refer to
+the commons project to get more information.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The main link for the
+commons project: <A HREF="http://jakarta.apache.org/commons/index.html">http://jakarta.apache.org/commons/index.html</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>junit-3.8.1.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The famous unit test
+library. Required if you like to build WSS4J from source and run the
+unit tests.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://www.junit.org/">http://www.junit.org/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>log4j-1.2.9.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The logging library.
+Required to control the logging, error reporting and so on.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://logging.apache.org/">http://logging.apache.org/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>opensaml-1.0.1.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The SAML
+implemetation used by WSS4J to implement the SAML profile.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://www.opensaml.org/">http://www.opensaml.org/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>wsdl4j-1.5.1.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The WSDL parsing
+functions, required by Axis tools to read and parse WSDL.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://ws.apache.org/axis/">http://ws.apache.org/axis/</A>
+under related projects</P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>xalan-2.7.0.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">Library that
+implements XML Path Language (XPath) and XSLT. The XML Security
+implementation needs several functions of Xalan XPath.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://xml.apache.org/xalan-j/">http://xml.apache.org/xalan-j/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>xmlsec-1.3.0.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">This library
+implements the XML-Signature Syntax and Processing and the XML
+Encryption Syntax and Processing specifications of the W3C. Thus they
+form one of the base foundations of WSS4J.</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://xml.apache.org/security/">http://xml.apache.org/security/</A></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Courier New"><FONT SIZE=2>xercesImpl.jar<BR>xml-apis.jar</FONT></FONT></P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">The XML parser
+implementation. Required by anybody :-) .</P>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">See:
+<A HREF="http://xml.apache.org/xerces2-j/">http://xml.apache.org/xerces2-j/</A></P>
+<P><BR><BR>
+</P>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/xdocs/api.xml b/xdocs/api.xml
new file mode 100644
index 0000000..2c94a03
--- /dev/null
+++ b/xdocs/api.xml
@@ -0,0 +1,541 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document><properties><title>Apache WSS4J API Overview</title></properties><body><section name="Apache WSS4J API Overview"></section><section name=""><subsection name="Contents"><ul>
+  <li><a href="#API_Overview">API Overview</a><br></br>
+  </li>
+  <ul>
+    <li><a href="#org.apache.ws.security.WSSecurityEngine">WSSecurityEngine</a></li>
+    <li><a href="#org.apache.ws.security.message.WSBaseMessage">WSBaseMessage</a></li>
+    <li><a href="#org.apache.ws.security.message.WSSignEnvelope">WSSignEnvelope</a> 
+(extends WSBaseMessage)</li>
+    <li><a href="#org.apache.ws.security.message.WSAddTimestamp">WSAddTimestamp</a> 
+(extends WSBaseMessage)</li>
+    <li><a href="#org.apache.ws.security.message.WSEncryptBody">WSEncryptBody</a>  
+(extends WSBaseMessage)</li>
+    <li><a href="#org.apache.ws.security.message.WSAddUsernameToken">WSAddUsernameToken</a>
+(extends WSBaseMessage)</li>
+    <li><a href="#org.apache.ws.security.message.WSSAddSAMLToken">WSSAddSAMLToken</a>
+(extends WSBaseMessage)</li>
+  </ul>
+  <li><a href="#Examples">Examples</a></li>
+  <ul>
+    <li>Sign the SOAP Body</li>
+    <li>Encrypt the SOAP Body</li>
+    <li>Process WSS Header and Check the Results<br></br>
+    </li>
+  </ul>
+</ul><br></br></subsection></section><section name=""><subsection name="API Overview"><p>WSS4J can be used as a library to provide an API for WS-Security
+processing. In this case WSS4J does not need to be used with Axis, or
+even be a part of a deployed web application. The WSS4J API can be
+invoked directly to create WS-Security headers or process them given a
+SOAP Envelope DOM Document.<br></br>
+</p><p>Following is an overview of the main classes and methods for the
+WSS4J API. Please refer to the java docs for the complete API
+documentation.<br></br>
+</p></subsection><subsection name="org.apache.ws.security.WSSecurityEngine"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Get an instance of security
+engine </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public static org.apache.ws.security.WSSecurityEngine getInstance()</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Get
+a singleton instance of security engine
+class. If you need to get an instance configured for an older spec
+(different namespaces) then use the other method which takes
+org.apache.ws.security.WSSConfig<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="4" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+    </tr>
+    <tr>
+    </tr>
+    <tr>
+    </tr>
+    <tr>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">
+      <pre>org.apache.ws.security.WSSecurityEngine</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">Processes
+WS-Security Headers in a SOAP Envelope<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Verify WSS Headers<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>java.util.Vector <b>processSecurityHeader</b>(<br></br>    org.w3c.dom.Document doc,<br></br>    java.lang.String actor,<br></br>    javax.security.auth.callback.CallbackHandler cb,<br></br>    org.apache.ws.security.components.crypto.Crypto crypto<br></br>    ) throws org.apache.ws.security.WSSecurityException</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and verifies the WSS Headers. 
+This
+includes Username Token processing, Signature verification, decryption
+and timestamp verification. In the case of encrypted elements,
+decryption is performed live on the passed document, i.e., it is
+transformed into the decrypted format.<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="4" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">actor</td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+engine works on behalf of this actor. Refer to the SOAP specification
+about actor or role, this may be null.<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold;">cb<br></br>
+      </td>
+      <td style="vertical-align: top;">a callback hander to the caller
+to resolve passwords during encryption and UsernameToken handling, this
+may be null.<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">crypto<br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+object that implements the access to the keystore and the handling of
+certificates. A default implementation is included:
+org.apache.ws.security.components.crypto.Merlin<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top;">
+      <pre>java.util.Vector</pre>
+      </td>
+      <td style="vertical-align: top;">Vector of
+org.apache.ws.security.WSSecurityEngineResult, this has the information
+resulting from the processing, such as the principal, SAML token, etc.<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSBaseMessage"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Set the Signature/Encryption
+parts<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public void setParts(java.util.Vector parts)</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a vector of org.apache.ws.security.WSEncryptionPart.<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="2" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">crypto<br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+object that implements the access to the keystore and the handling of
+certificates. A default implementation is included:
+org.apache.ws.security.components.crypto.Merlin<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top;">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top;">the
+SOAP Envelope Signed. The signed elements depend on the signature parts
+that are specified by the WSBaseMessage.setParts(java.util.Vector
+parts) method<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSSignEnvelope
+(extends WSBaseMessage)"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Signs a SOAP Envelope<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public org.w3c.dom.Document build(<br></br>    org.w3c.dom.Document doc,<br></br>    org.apache.ws.security.components.crypto.Crypto crypto<br></br>    ) throws org.apache.ws.security.WSSecurityException</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and adds WSS Signature header to it.
+The signed elements depend on the signature parts
+that are specified by the WSBaseMessage.setParts(java.util.Vector
+parts) method. By default, SOAP Body is signed </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="2" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">crypto<br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+object that implements the access to the keystore and the handling of
+certificates. A default implementation is included:
+org.apache.ws.security.components.crypto.Merlin<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top;">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top;">the
+SOAP Envelope signed.<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSAddTimestamp
+(extends WSBaseMessage)"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Add a Timestamp Token to a
+SOAP Envelope </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public org.w3c.dom.Document <b>build</b>(<br></br>    org.w3c.dom.Document doc,<br></br>    int ttl)</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and adds a Timestamp header to
+it. Please refer to the WS specification 1.0. chapter 10 / appendix A.2
+      <p> </p>
+      <p> </p>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="2" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">
+      <pre>ttl</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">(time
+to live) This is the time difference in seconds between the <code>Created</code>
+and the <code>Expires</code> in <code>Timestamp</code>, set to zero
+if <code>Expires</code> should not be added. </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(255, 255, 255);">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(255, 255, 255);">the
+SOAP Envelope with the Timestamp added<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSEncryptBody
+(extends WSBaseMessage)"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Encrypt a SOAP Envelope<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public org.w3c.dom.Document build(<br></br>    org.w3c.dom.Document doc,<br></br>    org.apache.ws.security.components.crypto.Crypto crypto<br></br>    ) throws org.apache.ws.security.WSSecurityException</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and adds WSS Encryption header to it.
+Unlike
+what the class name might imply, this can be used to encrypt elements
+in the SOAP Header, such as Username Tokens or other arbitrary
+elements. The encrypted elements depend on the signature parts
+that are specified by the WSBaseMessage.setParts(java.util.Vector
+parts) method. By default, SOAP Body is encrypted</td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="2" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">crypto<br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+object that implements the access to the keystore and the handling of
+certificates. A default implementation is included:
+org.apache.ws.security.components.crypto.Merlin<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top;">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top;">the
+SOAP Envelope encrypted.<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSAddUsernameToken
+(extends WSBaseMessage)"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Add a Username Token to a
+SOAP Envelope<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public org.w3c.dom.Document build(<br></br>    org.w3c.dom.Document doc,<br></br>    java.lang.String username,<br></br>    java.lang.String password)</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and adds a Username Token header to
+it. Use setPasswordType(java.lang.String pwType) to choose between
+plain text passwords and digested ones. </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="3" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">username<br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+username to use<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top;">password<br></br>
+      </td>
+      <td style="vertical-align: top;">the password to use (a plain
+text string)<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+SOAP Envelope with the username token header added<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="org.apache.ws.security.message.WSSAddSAMLToken
+(extends WSBaseMessage)"><table style="width: 100%; text-align: left;" border="0" cellpadding="4" cellspacing="4">
+  <tbody>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Action<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 204, 204); font-weight: bold;">Method<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle;">Add a SAML Token to a SOAP
+Envelope </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top;">
+      <pre>public org.w3c.dom.Document build(<br></br>    org.w3c.dom.Document doc,<br></br>    org.opensaml.SAMLAssertion assertion)</pre>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Description<br></br>
+      </td>
+      <td colspan="2" rowspan="1" style="vertical-align: top; background-color: rgb(204, 255, 255);">Takes
+a SOAP Envelope as a W3C Document and adds a SAML Assertion Token
+header to
+it. Please refer to the OpenSAML documentation on how to construct SAML
+assertions.<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="1" rowspan="2" style="vertical-align: middle; background-color: rgb(204, 204, 204); font-weight: bold;">Parameters<br></br>
+      </td>
+      <td style="vertical-align: top; font-weight: bold;">
+      <pre>doc</pre>
+      </td>
+      <td style="vertical-align: top;">the SOAP Envelope as W3C DOM
+Document</td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; font-weight: bold; background-color: rgb(204, 255, 255);">
+      <pre>assertion</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(204, 255, 255);">the
+SAML assertion to add<br></br>
+      </td>
+    </tr>
+    <tr>
+      <td style="vertical-align: top; background-color: rgb(204, 204, 204);"><span style="font-weight: bold;">Returns</span><br></br>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(255, 255, 255);">
+      <pre>org.w3c.dom.Document</pre>
+      </td>
+      <td style="vertical-align: top; background-color: rgb(255, 255, 255);">the
+SOAP Envelope with the SAML assertion header added<br></br>
+      </td>
+    </tr>
+  </tbody>
+</table><br></br></subsection><subsection name="Examples"></subsection><subsection name="Sign the SOAP Body"><small>Document envelope = ...<br></br>
+WSSignEnvelope signer = new WSSignEnvelope();<br></br>
+Crypto crypto = CryptoFactory.getInstance("crypto.properties");<br></br>
+Vector parts = new Vector();<br></br>
+WSEncryptionPart part = new
+WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),<br></br>
+                       
+                 
+   soapConstants.getEnvelopeURI(),<br></br>
+                 
+                          
+"Content");<br></br>
+parts.add(part);<br></br>
+signer.setParts(parts); // this is optional since the body is signed by
+default<br></br>
+envelope = signer.build(envelope, crypto);</small><br></br></subsection><subsection name="Encrypt the SOAP Body"><small>Document envelope = ...<br></br>
+WSEncryptBody encryptor = new WSEncryptBody();<br></br>
+Crypto crypto = CryptoFactory.getInstance("crypto.properties");<br></br>
+Vector parts = new Vector();<br></br>
+WSEncryptionPart part = new
+WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),<br></br>
+                       
+                 
+   soapConstants.getEnvelopeURI(),<br></br>
+                 
+                          
+"Content");<br></br>
+parts.add(part);<br></br>
+encryptor.setParts(parts); </small><small>// this is optional since
+the body is encrypted by default</small><br></br><small>envelope = encryptor.build(envelope, crypto);</small><br></br></subsection><subsection name="Process WSS Header and Check the Results"><small>
+Document envelope = ...<br></br>
+WSSecurityEngine secEngine = WSSecurityEngine.getInstance();<br></br>
+Crypto crypto = CryptoFactory.getInstance("crypto.properties");<br></br>
+<code>// </code><code>javax.security.auth.callback.CallbackHandler<br></br>
+// please refer to the tests for examples of callback handlers<br></br>
+</code><code>CallbackHandler cb = new MyCallbackHandler();</code><code></code><br></br>
+Vector results = secEngine.processSecurityHeader(envelope, null, <code>cb</code>,
+crypto);<br></br>
+for (int i = 0; i &lt; results.size(); i++) {<br></br>
+    WSHandlerResult hResult =
+(WSHandlerResult)results.get(i);<br></br>
+    String actor = hResult.getActor();<br></br>
+    Vector hResults = hResult.getResults();<br></br>
+    for (int j = 0; j &lt; hResults.size(); j++) {<br></br>
+        WSSecurityEngineResult
+eResult = (WSSecurityEngineResult)hResults.get(j);<br></br>
+        // Note: an encryption
+action does not have an associated principal<br></br>
+        // only Signature and
+UsernameToken actions return a principal<br></br>
+        if (eResult.getAction() !=
+WSConstants.ENCR) {<br></br>
+           
+System.out.println(eResult.getPrincipal().getName());<br></br>
+        }<br></br>
+    }<br></br>
+}</small><br></br></subsection></section></body></document>
\ No newline at end of file
diff --git a/xdocs/axis.xml b/xdocs/axis.xml
new file mode 100644
index 0000000..7325365
--- /dev/null
+++ b/xdocs/axis.xml
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document><properties><title>Axis Deployment Tutorial</title></properties><body><section name="Apache WSS4J"></section><section name="Axis Deployment Tutorial"></section><section name=""><subsection name="Contents"><ul>
+  <li>Introduction</li>
+  <li>Prerequisties</li>
+  <li>Steps</li>
+  <ul>
+    <li>Username Token<br></br>
+    </li>
+  </ul>
+</ul></subsection></section><section name=""><subsection name="Introduction"><div style="margin-left: 40px;">WSS4J can be used for securing web
+services deployed in virtually any application server, but it includes
+special support for Axis. WSS4J ships with handlers that can be used in
+Axis-based web
+services for an easy integration. These handlers can be added to the
+service deployment
+descriptor (wsdd file) to add a WS-Security layer to the web service.
+This is a step by step tutorial for deploying a simple service with
+Username Token.<br></br>
+</div><br></br></subsection><subsection name="Prerequisties"><div style="margin-left: 40px;"><a href="http://ws.apache.org/axis/">Axis
+1.2</a> installed and configured on a <a href="http://jakarta.apache.org/tomcat/">Tomcat Server</a>.  This
+tutorial was performed on a Linux machine with Tomcat 5.5.4/Java 1.5.0,
+however, the setup should be similar on other application servers, or
+other operating systems (like Windows) unless we stated otherwise.<br></br>
+</div></subsection><subsection name="Steps"></subsection><subsection name="    Installing WSS4J"><div style="margin-left: 40px;">
+<ol>
+  <li>Download the WSS4J binaries or build it from sources<br></br>
+  </li>
+  <li>Copy the contents of the WSS4J lib directory to your Axis
+WEB-INF/lib directory. Many jar files will already exist. Most of them
+will already exist there but you can just overwrite them all.</li>
+  <li>You may need to restart Tomcat unless you have automatic
+deployment/class loading turned on. Check the Axis Happiness Page
+(typically at http://localhost:8080/axis), make sure that the XML
+Security (xmlsec.jar) is listed under the "Optional Components" section.</li>
+</ol>
+<h4>Creating the Service</h4>
+</div><ol>
+  <ol>
+    <li>This tutorial will secure the StockQuoteService which ships
+with Axis. Unless you have one already, create a deployment descriptor
+(deploy.wsdd) file with the following contents:</li>
+  </ol>
+</ol><div style="margin-left: 40px;">
+<ol start="2">
+  <br></br>
+  <span style="color: rgb(0, 0, 153);">&lt;deployment
+xmlns="http://xml.apache.org/axis/wsdd/"
+xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);"> &lt;service
+name="stock-wss-01" provider="java:RPC" style="document"
+use="literal"&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="className" value="samples.stock.StockQuoteService"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="allowedMethods" value="getQuote"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="scope" value="application"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);"> &lt;/service&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+  <span style="color: rgb(0, 0, 153);">&lt;/deployment&gt;<br></br>
+  <br></br>
+  </span><li>deploy the service (using AxisAdmin):</li>
+</ol>
+</div><div style="margin-left: 40px;">
+<ol>
+  <span style="color: rgb(0, 0, 153);">java
+org.apache.axis.client.AdminClient
+-lhttp://localhost:8080/axis/services/AdminService deploy.wsdd<br></br>
+  </span>
+</ol>
+<h4>Creating the Client</h4>
+<ol>
+  <li>Use WSDL2Java to generate the client service bindings:<br></br>
+    <span style="color: rgb(0, 0, 153);">java
+org.apache.axis.wsdl.WSDL2Java -o .
+-Nhttp://fox:8080/axis/services/stock-wss-01 samples.stock.client
+http://fox:8080/axis/services/stock-wss-01?wsdl</span><br></br>
+    <br></br>
+A bunch of java classes will be created under samples/stock/client,
+including the StockQuoteServiceServiceLocator.<br></br>
+    <br></br>
+  </li>
+  <li>Write a simple java client that uses the generated service
+locator. For example:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">package samples.stock.client;</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+java.rmi.RemoteException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.xml.rpc.ServiceException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">public class
+StockServiceClient {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    public
+StockServiceClient() {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    }</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    public
+static void main(String[] args) throws ServiceException,
+RemoteException {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+if (args.length == 0) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+System.out.println("Usage:\njava StockServiceClient [symbol]");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+return;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+StockQuoteServiceService locator = new
+StockQuoteServiceServiceLocator();</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+StockQuoteService service = locator.getStockWss01();</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+float quote = service.getQuote(args[0]);</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+System.out.println("stock quote service returned " + args[0] + ": " +
+quote);</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    }</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">}</span><br></br>
+    <br></br>
+  </li>
+  <li>run the client:<br></br>
+    <span style="color: rgb(0, 0, 153);">java
+samples.stock.client.StockServiceClient IBM</span><br></br>
+    <br></br>
+If all went well, you should get the result:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);"></span> <span style="color: rgb(0, 0, 153);">stock quote service returned IBM: 95.68</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"><br></br>
+    </span></li>
+</ol>
+</div><div style="margin-left: 40px;">
+<h3>Username Token</h3>
+<h4>Configuring the Service<br></br>
+</h4>
+<ol>
+  <li>Modify the deployment descriptor you created above to look like
+this:<br></br>
+    <span style="color: rgb(0, 0, 153);">&lt;deployment
+xmlns="http://xml.apache.org/axis/wsdd/"
+xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> &lt;service
+name="stock-wss-01" provider="java:RPC" style="document"
+use="literal"&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;"> 
+&lt;requestFlow&gt;</span><br style="color: rgb(0, 0, 153); font-weight: bold;"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;">  
+&lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver"&gt;</span><br style="color: rgb(0, 0, 153); font-weight: bold;"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;">   
+&lt;parameter name="passwordCallbackClass" value="PWCallback"/&gt;</span><br style="color: rgb(0, 0, 153); font-weight: bold;"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;">   
+&lt;parameter name="action" value="UsernameToken"/&gt;</span><br style="color: rgb(0, 0, 153); font-weight: bold;"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;"></span><span style="color: rgb(0, 0, 153); font-weight: bold;">  
+&lt;/handler&gt;</span><br style="color: rgb(0, 0, 153); font-weight: bold;"></br>
+    <span style="color: rgb(0, 0, 153); font-weight: bold;"> 
+&lt;/requestFlow&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="className" value="samples.stock.StockQuoteService"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="allowedMethods" value="getQuote"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">  &lt;parameter
+name="scope" value="application"/&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> &lt;/service&gt;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">&lt;/deployment&gt;<br></br>
+    <br></br>
+    </span>WSDoAllReceiver is an Axis handler that can be located in
+wss4j.jar. This is the standard way to deploy an Axis handler. For more
+details please refer to the Axis handler for WSS4J documentation.<br></br>
+    <br></br>
+  </li>
+  <li>Create a class named PWCallback.java and compile it into your
+Axis WEB-INF/classes directory. In this example I used the default
+package for simplicity, but you might need to use the fully qualified
+class name (be consistent
+with the deployment descriptor).<br></br>
+    <br></br>
+The following code snippet shows a simple password callback class:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">import java.io.IOException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.Callback;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.CallbackHandler;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.UnsupportedCallbackException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+org.apache.ws.security.WSPasswordCallback;</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">public class PWCallback
+implements CallbackHandler {</span><span style="color: rgb(0, 0, 153);"></span><span style="color: rgb(0, 0, 153);"></span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    public void
+handle(Callback[] callbacks)</span><span style="color: rgb(0, 0, 153);">
+throws IOException, UnsupportedCallbackException {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+for (int i = 0; i &lt; callbacks.length; i++) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+if (callbacks[i] instanceof WSPasswordCallback) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];<br></br>
+               
+// set the password given a username<br></br>
+    </span>               
+    <span style="color: rgb(0, 0, 153);">if
+("wss4j".equals(pc.getIdentifer())) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">                   
+pc.setPassword("security");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"></span><span style="color: rgb(0, 0, 153);">           
+} else {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+throw new UnsupportedCallbackException(</span><span style="color: rgb(0, 0, 153);">callbacks[i], "Unrecognized Callback");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    }</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">}</span><br></br>
+    <span style="font-weight: bold;"></span><br></br>
+    <br></br>
+    <br></br>
+  </li>
+  <li>Redeploy the service. Your service should now be expecting a WSS
+Username Token in in the incoming requests, and clients should send the
+username "wss4j" and password "security" to get through.<br></br>
+  </li>
+</ol>
+<h4>Configuring the Client</h4>
+<ol>
+  <li>run the client we created again:<br></br>
+    <span style="color: rgb(0, 0, 153);">java
+samples.stock.client.StockServiceClient IBM</span><br></br>
+    <br></br>
+You should now get an error:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">Exception in thread "main"
+AxisFault</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> faultCode:
+{http://schemas.xmlsoap.org/soap/envelope/}Server.generalException</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> faultSubcode:</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> faultString:
+WSDoAllReceiver: Request does not contain required Security header</span><br></br>
+    <br></br>
+This is because your client is not configured to send a Username Token
+yet, so the service is rejecting the request.<br></br>
+    <br></br>
+  </li>
+  <li>Create a deployment descriptor file (client_deploy.wsdd) for the
+client:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">&lt;deployment
+xmlns="http://xml.apache.org/axis/wsdd/"
+xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"&gt;<br></br>
+ &lt;transport name="http"
+pivot="java:org.apache.axis.transport.http.HTTPSender"/&gt;<br></br>
+  &lt;globalConfiguration &gt;<br></br>
+   &lt;requestFlow &gt;<br></br>
+    &lt;handler
+type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;<br></br>
+     &lt;parameter name="action"
+value="UsernameToken"/&gt;<br></br>
+     &lt;parameter name="user" value="wss4j"/&gt;<br></br>
+     &lt;parameter name="passwordCallbackClass"
+value="samples.stock.client.PWCallback"/&gt;<br></br>
+     &lt;parameter name="passwordType"
+value="PasswordDigest"/&gt;<br></br>
+    &lt;/handler&gt;<br></br>
+   &lt;/requestFlow &gt;<br></br>
+  &lt;/globalConfiguration &gt;<br></br>
+&lt;/deployment&gt;</span><span style="color: rgb(0, 0, 153);"></span><br></br>
+    <br></br>
+  </li>
+  <li>Create the <span style="color: rgb(0, 0, 153);">samples.stock.client.PWCallback</span>
+class:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">package samples.stock.client;</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import java.io.IOException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.Callback;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.CallbackHandler;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+javax.security.auth.callback.UnsupportedCallbackException;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+org.apache.ws.security.WSPasswordCallback;</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">/**</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> * PWCallback for the
+Client</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);"> */</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">public class PWCallback
+implements CallbackHandler {</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    /**</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">     *
+@see
+javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">     */</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    public void
+handle(Callback[] callbacks) throws IOException,</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">                   
+UnsupportedCallbackException {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+for (int i = 0; i &lt; callbacks.length; i++) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+if (callbacks[i] instanceof WSPasswordCallback) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+// set the password given a username</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+if ("wss4j".equals(pc.getIdentifer())) {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">                   
+pc.setPassword("security");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+} else {</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">               
+throw new UnsupportedCallbackException(callbacks[i], "Unrecognized
+Callback");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">           
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">       
+}</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">    }</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">}</span><br></br>
+    <br></br>
+  </li>
+  <li>Define the system property axis.ClientConfigFile for your client:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">java
+-Daxis.ClientConfigFile=client_deploy.wsdd -classpath $AXISCLASSPATH
+samples.stock.client.StockServiceClient</span><br></br>
+    <br></br>
+Make sure that your classpath includes the jar files under WEB-INF/lib.<br></br>
+    <br></br>
+Another way to do this is to specify the wsdd file in your
+StockServiceClient to the service locator programmatically:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">...</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+org.apache.axis.EngineConfiguration;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+org.apache.axis.configuration.FileProvider;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">...</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">EngineConfiguration config =
+new FileProvider("client_deploy.wsdd");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">StockQuoteServiceService
+locator = new StockQuoteServiceServiceLocator(config);</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">...</span><br></br>
+    <br></br>
+  </li>
+  <li>Run the client, you should get no errors:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">stock quote service returned
+IBM: 95.7</span><br></br>
+    <br></br>
+Your client is now sending a Username Token in the wsse request header
+with the username "wss4j" (see client_deploy.wsdd) and password
+"security" (see the PWCallback implementation).<br></br>
+    <br></br>
+Another way to do this is to have the client application set the
+username and CallbackHandler implementation programmatically instead of
+client_deploy.wsdd:<br></br>
+    <br></br>
+    <span style="color: rgb(0, 0, 153);">...</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">import
+org.apache.axis.client.Stub;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">...</span><br style="color: rgb(0, 0, 153);"></br>
+    <br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">Remote remote =
+locator.getPort(StockQuoteService.class);</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">Stub axisPort = (Stub)remote;</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">axisPort._setProperty(UsernameToken.PASSWORD_TYPE,
+WSConstants.PASSWORD_DIGEST);</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">axisPort._setProperty(WSHandlerConstants.USER,
+"wss4j");</span><br style="color: rgb(0, 0, 153);"></br>
+    <span style="color: rgb(0, 0, 153);">axisPort._setProperty(WSHandlerConstants.PW_CALLBACK_REF,
+pwCallback);</span><br></br>
+    <br></br>
+where "pwCallback" is a reference to a PWCallback implementation. See
+the Axis handler for WSS4J documentation for more details on this.<br></br>
+    <br></br>
+  </li>
+  <li>Try modifying your client's PWCallback to return the wrong
+password, or send the wrong username. The service should reject your
+requests.</li>
+</ol>
+<br></br>
+</div><br></br><br></br><div style="margin-left: 40px;"></div></subsection></section></body></document>
\ No newline at end of file
diff --git a/xdocs/cert.xml b/xdocs/cert.xml
new file mode 100644
index 0000000..8e898ab
--- /dev/null
+++ b/xdocs/cert.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<document>
+<properties>
+<author email="gtr@ast.cam.ac.uk">Guy Rixon</author>
+<title>Including the sender's certificate in the signed message</title>
+</properties>
+
+<body>
+<section name="Including the sender's certificate in the signed message">
+<p>
+When messages are digitally signed, the recipient must have the sender's
+certificate chain in order to check the signature. Typically, the chain has
+two certificates: that of the sender and that of the sender's certificate
+authority (CA).
+</p>
+<p>
+There are two common ways of getting the certificates to the service.
+</p>
+<ol>
+<li>
+Install the CA's certificate in the service configuration. Send the caller's
+individual certificate with the signed message. This is called "direct reference",
+since the signature mark-up in the SOAP header refers directly to an included
+credential.
+</li>
+<li>
+Install both the CA certificate and the caller's individual certificate in the
+service configuration. Send the CA's name and the serial number of the caller's
+certificate in the SOAP message; have the service retrieve its copy of the certificate
+using these metadata. This is called the "issuer-serial" method.
+</li>
+</ol>
+<p>
+The issuer-serial method presumes that all trusted users of the service are known to the
+service and have pre-registered
+their certificate chains before using the service. The direct-reference method presumes
+that the service operator trusts all users with certificates issued by a trusted CA.
+</p>
+<p>
+To use the direct-reference method when using WSDoAllSender to sign the messages, the client must
+set a handler property as follows.
+</p>
+<pre>
+stub._setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
+</pre>
+<p>
+To use the issuer-serial method, the property should be set like this:
+</p>
+<pre>
+stub._setProperty(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");
+</pre>
+<p>
+If the property is not set, the default in WSS4J is to use the issuer-serial method.
+</p>
+</section>
+</body>
+
+</document> 
diff --git a/xdocs/index.xml b/xdocs/index.xml
new file mode 100644
index 0000000..0b8bef8
--- /dev/null
+++ b/xdocs/index.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document>
+    <properties>
+        <title>WSS4J Documentation</title>
+    </properties>
+    <body>
+        <section name="Apache WSS4J"/>
+        <section name="">
+            <subsection name="Contents">
+                <ul>
+                    <li>
+                        <a href="#What_is_WSS4J">What is WSS4J?</a>
+                    </li>
+                    <li>
+                        <a href="#Where_can_I_download_WSS4J">Where can i download WSS4J?</a>
+                    </li>
+                    <li>
+                        <a href="#WS-Security%20Features">WS-Security Features</a>
+                    </li>
+                    <li>
+                        <a href="#WSS4J_Use_Cases">WSS4J Use Cases</a>
+                    </li>
+                    <ul>
+                        <li>WSS4J API</li>
+                        <li>WSS4J on Axis</li>
+                        <li>Rampart: WS-Security Implementation module for Axis2</li>
+                    </ul>
+                </ul>
+                <br/>
+            </subsection>
+        </section>
+        <section name="">
+            <subsection name="What is WSS4J?">
+                <p style="margin-left: 40px;"> 
+Apache WSS4J is an implementation of the
+OASIS Web Services Security (WS-Security) from <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss">OASIS
+Web Services Security TC</a>. WSS4J is a primarily a Java library that can be used to sign and verify SOAP Messages 
+with WS-Security information. WSS4J will use Apache Axis and Apache XML-Security projects and will be interoperable 
+with JAX-RPC based server/clients and .NET server/clients.
+<br/>
+                </p>
+                <p style="margin-left: 40px;">WSS4J implements<br/>
+                </p>
+                <ul style="margin-left: 40px;">
+                    <li>
+                        <a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf">OASIS
+Web Serives Security: SOAP Message Security 1.0 Standard 200401, March
+2004</a>
+                    </li>
+                    <li>
+                        <a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf">Username
+Token profile V1.0</a>
+                    </li>
+                    <li>
+                        <a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0.pdf">X.509
+Token Profile V1.0</a>
+                    </li>
+                </ul>
+            </subsection>
+            <subsection name="Where can I download WSS4J">
+                <p style="margin-left: 40px;">Latest version of WSS4J is 1.5.0:<br/>
+                    <a href="http://www.apache.org/dyn/closer.cgi/ws/wss4j/">http://www.apache.org/dyn/closer.cgi/ws/wss4j/</a>
+                </p>
+            </subsection>
+            <subsection name="WS-Security Features">
+                <p style="margin-left: 40px;">WSS4J can generate and process the
+following SOAP Bindings:<br/>
+                </p>
+                <ul>
+                    <ul>
+                        <li>XML Security<br/>
+                        </li>
+                        <ul>
+                            <li>XML Signature</li>
+                        </ul>
+                        <ul>
+                            <li>XML Encryption</li>
+                        </ul>
+                        <li>Tokens</li>
+                        <ul>
+                            <li>Username
+Tokens</li>
+                            <li>Timestamps</li>
+                        </ul>
+                        <ul>
+                            <li>SAML Tokens</li>
+                        </ul>
+                    </ul>
+                </ul>
+                <div style="margin-left: 40px;">WSS4J supports X.509 binary
+certificates and certificate paths.<br/>
+                    <br/>
+                </div>
+                <p style="margin-left: 40px;"/>
+            </subsection>
+            <subsection name="WSS4J API">
+                <p style="margin-left: 40px;">Please refer to the <a href="api.html">API
+Overview</a>
+for details.<br/>
+                    <br/>
+                </p>
+            </subsection>
+            <subsection name="WSS4J on Axis">
+                <p style="margin-left: 40px;">Please refer to the the <a href="axis.html">Axis
+Deployment Tutorial</a> for a short tutorial and <a href="package.html">Axis Deployment Examples</a> for more details.<br/>
+                </p>
+                <br/>
+            </subsection>
+			<subsection name="Rampart: WS-Security Implementation module for Axis2">
+                <p style="margin-left: 40px;">Please refer to the the 
+				<a href="http://svn.apache.org/viewcvs.cgi/*checkout*/webservices/axis2/trunk/java/xdocs/latest/security-module.html">
+				Rampart configuration guide</a> for configuration information<br/>
+                </p>
+                <br/>
+            </subsection>
+            <subsection name="WSS4J Configuration">
+                <p style="margin-left: 40px;"><a href="cert.html">Difference between issuer-serial (WSS4J default) and direct-reference modes</a> 
+                </p>
+                <br/>
+            </subsection>
+        </section>
+    </body>
+</document>
diff --git a/xdocs/package.xml b/xdocs/package.xml
new file mode 100644
index 0000000..565666f
--- /dev/null
+++ b/xdocs/package.xml
@@ -0,0 +1,648 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document><properties><title>Axis Deployment Examples</title></properties><body><section><p>
+
+WSS4J Axis handlers process SOAP requests according to the OASIS Web Service 
+Security (WSS) specifications.
+</p><p></p><p>
+The WSS4J Axis handlers <code>WSDoAllSender</code> and <code>WSDoAllReceiver
+</code> control the creation and consumption of secure SOAP requests.
+The handlers work behind the scenes and are usually transparent to Web Service
+(WS) applications. The Axis deployment descriptor files (*.wsdd) may contain all
+necessary information to control the security processing.
+</p><p></p><p>
+A WS application may also set properties to control the handlers
+and provide default values. If the deployment descriptor sets the same 
+property (parameter) then the deployment descriptor overwrites the application
+defined property.  Thus, deployment settings overwrite application settings 
+to fulfill site specific requirements.
+
+</p></section><section name="Prerequisties"><p>
+The WS Security Axis handlers use the WSS4J classes (Web Service Security 
+for Java) to process the SOAP messages. WSS4J in turn uses the Apache XML Security 
+project to handle XML Security according to XML Signature and XML Encryption. 
+
+<ul>
+  <li><a href="http://ws.apache.org/wss4j/index.html">WSS4J</a></li>
+  <li><a href="http://xml.apache.org/security/index.html">XML Security</a></li>
+</ul>
+
+The WSS4J Axis handlers require Axis V1.2 because of some problems in previous
+Axis versions. WSS4J CVS contains the latest Axis libraries. 
+
+</p></section><section name="Related Documentation"><p>
+The OASIS WSS specifications define a number of features and it is possible 
+to combine them in several ways. The WSS4J Axis handlers already support 
+a large number of WSS features and their combinations. 
+<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss">
+Here</a> are the WSS specifications.
+
+</p></section><section name="The basics - a simple example that uses"><p>
+This chapter gives an overview and some examples how to deploy 
+the WSS4J Axis handlers and how the parameters and their values control the
+handlers. For a better understanding of this chapter the reader shall 
+have a knowledge of the OASIS WSS specifications.
+</p><p></p><p>
+The {@link org.apache.ws.security.handler.WSHandlerConstants}, 
+{@link org.apache.ws.axis.security.WSDoAllSender}, and 
+{@link org.apache.ws.axis.security.WSDoAllReceiver}
+provide additional and detailed documentation.
+
+</p><subsection name="Axis deployment descriptor to insert a"><p>
+The following snippet shows a general layout how to deploy a WS Axis handler
+on the client (application) side.
+<source>
+ &lt;!-- define the service, use the WSDoAllSender security handler in request flow --&gt;
+ &lt;service name="Ping1"&gt;
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;
+    &lt;parameter name="action" value="UsernameToken"/&gt;
+    &lt;parameter name="user" value="werner"/&gt;
+    &lt;parameter name="passwordType" value="PasswordText" /&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback1"/&gt;
+   &lt;/handler&gt;
+  &lt;/requestFlow&gt;
+  &lt;/service&gt;
+</source>
+
+This is the standard way to deploy an Axis handler. Axis parses the deployment
+descriptor and provides the parameters and their value to the handler. Each
+service can have its own request and response flow definition, which provides
+a very flexible set-up of the security parameters.
+</p><p></p><p>
+The above setup inserts the most simple security structure into a SOAP request: 
+the simple <code>UsernameToken</code>. This token includes a username and the 
+according password. Both fields are sent in cleartext, thus it provides no 
+real security.
+</p><p></p><p>
+
+The parameters and their meanings are:
+<ul>
+<li><code>action</code> defines the security action. The value <code>
+    UsernameToken</code> directs the handler to insert this token into
+    the SOAP request.
+</li>
+<li><code>user</code> specifies the username to include in the token.
+</li>
+<li><code>passwordType</code> is a pecific parameter for the <code>
+    UsernameToken</code> action and defines the encoding of the passowrd.
+    <code>PasswordText</code> specifies to send the password in
+    plain text, <code>PasswordDigest</code> specifies to send the
+    password in digest mode (refer to WSS UsernameToken Profile)
+</li>
+<li><code>passwordCallbackClass</code> contains the name of a class that
+    implements a method to get the user's password. Please refer to the
+    detailed documentation in 
+    {@link org.apache.ws.security.handler.WSHandlerConstants#PW_CALLBACK_CLASS}.
+    </li>
+</ul>
+The WSS4J Axis security handler interprets the parameter values and controls
+the WSS4J modules to generate the following SOAP request:
+<source>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+  &lt;soapenv:Header&gt;
+    &lt;wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext" 
+      soapenv:mustUnderstand="true"&gt;
+      &lt;wsse:UsernameToken&gt;
+        &lt;wsse:Username&gt;werner&lt;/wsse:Username&gt;
+        &lt;wsse:Password Type="wsse:PasswordText"&gt;security&lt;/wsse:Password&gt;
+      &lt;/wsse:UsernameToken&gt;
+    &lt;/wsse:Security&gt;
+  &lt;/soapenv:Header&gt;
+  &lt;soapenv:Body&gt;
+    &lt;Ping xmlns="http://xmlsoap.org/Ping"&gt;
+      &lt;text&gt;Scenario 1 text&lt;/text&gt;
+      &lt;ticket xmlns:ns1="http://xmlsoap.org/Ping" 
+        xsi:type="ns1:ticketType"&gt;scenario1&lt;/ticket&gt;
+    &lt;/Ping&gt;
+  &lt;/soapenv:Body&gt;
+&lt;/soapenv:Envelope&gt;
+</source>
+This is a pretty print of the real SOAP message.
+
+</p></subsection><subsection name="The password callback class"><p>
+
+The deployment descriptor contains the user name that the handler inserts into
+the <code>UsernameToken</code> but not the password. In general it is not a
+good idea to store sensitive information like a password in cleartext. To
+get the password the WSS4J Axis handler uses a password callback
+technique similar to the JAAS mechansim. The parameter 
+<code>passwordCallbackClass</code> contains the classname of the callback
+class. This class must implement the
+{@link javax.security.auth.callback.CallbackHandler}
+interface. The WSS4J Axis handler gets this class,
+instantiates it, and calls the <code>handle</code> method when it
+needs a password. Refer also to the 
+{@link org.apache.ws.security.handler.WSHandlerConstants#PW_CALLBACK_CLASS
+ parameter} documentation.
+ </p><p></p><p>
+ The following code snippet shows a simple password callback class:
+ <source>
+package org.apache.ws.axis.oasis;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.ws.security.WSPasswordCallback;
+
+public class PWCallback implements CallbackHandler {
+
+  private static final byte[] key = {
+    (byte)0x31, (byte)0xfd, (byte)0xcb, (byte)0xda,
+    (byte)0xfb, (byte)0xcd, (byte)0x6b, (byte)0xa8,
+    (byte)0xe6, (byte)0x19, (byte)0xa7, (byte)0xbf,
+    (byte)0x51, (byte)0xf7, (byte)0xc7, (byte)0x3e,
+    (byte)0x80, (byte)0xae, (byte)0x98, (byte)0x51,
+    (byte)0xc8, (byte)0x51, (byte)0x34, (byte)0x04,
+  };
+	
+  public void handle(Callback[] callbacks)
+    throws IOException, UnsupportedCallbackException {
+    for (int i = 0; i &lt; callbacks.length; i++) {
+      if (callbacks[i] instanceof WSPasswordCallback) {
+        WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+        /*
+         * here call a function/method to lookup the password for
+         * the given identifier (e.g. a user name or keystore alias)
+         * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
+         * for testing we supply a fixed name/fixed key here.
+         */
+        if (pc.getUsage() == WSPasswordCallback.KEY_NAME) {
+          pc.setKey(key);
+        }
+        else {
+          pc.setPassword("security");
+        }
+      } else {
+        throw new UnsupportedCallbackException(
+          callbacks[i], "Unrecognized Callback");
+      }
+    }
+  }
+}
+</source>
+The Java {@link javax.security.auth.callback.CallbackHandler callback} handler
+documentation provides a detailed description of the interface and exceptions.
+</p><p></p><p>
+The WSS4J library uses a specific class to get the required password or key
+informations. The <code>WSSPasswordCallback</code> class implements the
+{@link javax.security.auth.callback.Callback} interface according to the
+JAAS. Depending on it usage this class either carries the required password
+as a Java <code>String </code> or it carries the required key information 
+as a Java <code>byte[]</code> array. Refer to
+{@link org.apache.ws.security.WSPasswordCallback} that contains a
+detailed description of the usage codes.
+</p><p></p><p>
+The WSS4J Axis handler or the WSS4J modules set the usage code before
+they call <code>handle</code> method. 
+
+</p></subsection><subsection name="Application sets parameters to insert in"><p>
+
+Sometimes it is not feasable or not possible to determine parameters
+and their values during deployment. In this case the application can
+set paramters during runtime. The WSS4J Axis handlers use the Axis
+<code>setProperty</code> method to support this feature.
+</p><p></p><p>
+The following code snippet shows an example how to use the dynamic setting
+of parameters and their values:
+<source>
+   ...
+ Service service = new Service();
+ Call call = (Call) service.createCall();
+   ...  
+ call.setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+ call.setProperty(WSHandlerConstants.USER, "werner");
+   ...
+</source>
+Use this way if your application dynamically creates a <code>call</code>
+object. If your application uses stubs generated by Axis' <code>WSDL2Java
+</code> tool, the application uses the following functions:
+<source>
+    ...
+ PingServiceLocator service = new PingServiceLocator();
+    ...
+ PingPort port = (PingPort) service.getPing1();
+ port._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+ port._setProperty(WSHandlerConstants.USER, "werner");
+    ...
+</source>
+Please note that <code>_setProperty</code> is a Axis specific call.
+
+</p></subsection><subsection name="The password callback object reference"><p>
+
+In addition to the <a href="#pwCallBackClass">password callback class</a>
+an application may set a password callback object using the <code>
+  setProperty()</code> methods. Only applications (and Axis handlers that
+  preceed the WSS4J Axis handlers in a handler chain) can use this feature.
+  </p><p></p><p>
+  For example:
+  <source>
+public class Scenario1 implements CallbackHandler {
+
+  public static void main(String args[]) {
+    ...
+    PingServiceLocator service = new PingServiceLocator();
+    ...
+    PingPort port = (PingPort) service.getPing1();
+    ((org.apache.axis.client.Stub)port)._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
+    ((org.apache.axis.client.Stub)port._setProperty(WSHandlerConstants.USER, "werner");
+    ((org.apache.axis.client.Stub)port._setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
+    ...
+  }
+
+  public void handle(Callback[] callbacks) {
+    ...
+  }
+}
+</source>
+
+</p></subsection><subsection name="Deployment of the WSS4J Axis  handler"><p>
+
+Similar to the deployment descriptor of the sending handler <code>WSDoAllSender
+</code> a deployment descriptor for the receiving handler exists. For the above
+example the deployment descriptor look like:
+<source>
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver"&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="action" value="UsernameToken"/&gt;
+   &lt;/handler&gt;
+  &lt;/requestFlow&gt;
+</source>
+The receiving WSS4J Axis handler checks if the SOAP request matches the defined
+actions.
+
+</p></subsection></section><section name="Combining security actions"><p>
+
+Often it is necessary to combine or concatenate several security actions, for 
+example to encrypt parts of a message and sign some other parts. The WSS4J 
+Axis handlers provide easy and simple methods to combine or concatenate
+security actions. 
+</p><p></p><p>
+This chapter describes simple combinations of actions.
+
+</p><subsection name="Combine  and"><p>
+
+The WS Interoperability specifications define this use case: 
+<ul>
+  <li>Insert a <code>UsernameToken</code>, use <code>PasswordText</code>
+    to set the password. In addition add a timestamp and a nonce into
+    the <code>UsernameToken</code></li>
+  <li>Encrypt the <code>UsernameToken</code> to protect the information.
+    </li>
+</ul>
+
+The Axis deplyment descriptor for this use case:
+<source>
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;
+    &lt;parameter name="action" value="UsernameToken Encrypt"/&gt;
+    &lt;parameter name="user" value="werner"/&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="passwordType" value="PasswordText" /&gt;
+    &lt;parameter name="addUTElement" value="Nonce Created" /&gt;
+    &lt;parameter name="encryptionPropFile" value="crypto.properties" /&gt;
+    &lt;parameter name="encryptionKeyIdentifier" value="X509KeyIdentifier" /&gt;
+    &lt;parameter name="encryptionUser" 
+      value="16c73ab6-b892-458f-abf5-2f875f74882e" /&gt;
+    &lt;parameter name="encryptionParts" 
+      value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken" /&gt;  
+   &lt;/handler&gt;
+  &lt;/requestFlow&gt;  
+</source>
+
+This descriptor contains some new parameters to control the <code>UsernameToken
+</code> element and its encryption. The new parameters and their meaning are:
+<ul>
+  <li><code>addUTElement</code> - controls if the handler shall insert elements
+    into the <code>UsernameToken</code>. The value is a blank separated list of
+    element names to include. Only <code>Nonce</code> and <code>Created</code> are
+    supported.</li>
+  <li><code>encryptionPropFile</code> - the name of a crypto property file. This
+    file contains parameters and property that control the encryption. Please refer
+    to the
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_PROP_FILE 
+    detailed} description of the cyrpto property file.</li>
+  <li><code>encryptionKeyIdentifier</code> - specifies the format in which the 
+    handler inserts the encryption key into the SOAP request. Please refer
+    to the 
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_KEY_ID 
+    detailed} description.</li>
+  <li><code>encryptionUser</code> - the name or identifier of the user who owns
+    the public key to encrypt the data. Usually this is the name or alias name
+    of the owner's certificate in a keystore.</li>
+  <li><code>encryptionParts</code> - controls which part or parts the handler
+    of the SOAP shall encrypt. If this parameter is not defined, WSS4J encrypts
+    the whole SOAP Body in <code>Content</code> mode. The value of the
+    parameter in this example specifies to encrypt the element <code>
+    UsernameToken</code>, contained in the namespace
+    <code>http://schemas.xmlsoap.org/ws/2002/07/secext</code>. The encryption
+    module uses the <code>Element</code> mode to encrypt the element data.
+    Please refer to the
+    {@link org.apache.ws.security.handler.WSHandlerConstants#ENCRYPTION_PARTS 
+    detailed} description.
+    </li>
+</ul>
+The matching receiver deployment descriptor:
+<source>
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver"&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="action" value="UsernameToken Encrypt"/&gt;
+    &lt;parameter name="decryptionPropFile" value="crypto.properties" /&gt;
+   &lt;/handler&gt;
+  &lt;/requestFlow&gt;
+</source>
+The only new parameter here is the <code>decryptionPropFile</code>. This
+parameter defines the crypto property file at the receiver side. The value
+  of the <code>action</code> parameter matches the according value at the
+  sender side. The WSS4J Axis receiver checks if the SOAP request contains
+  the required security data.
+
+</p></subsection><subsection name="Combine Signature and Encryption"><p>
+
+This is a very common usage of Web Service security. The WSS4J Axis handler
+provides flexible parameter settings that support several ways to use
+the Signature/Encryption combination.
+</p><p></p><p>
+A WSS4J Axis deployment descriptor for a simple Singature/Encryption of
+SOAP requests:
+<source>
+&lt;requestFlow&gt;
+  &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;
+    &lt;parameter name="user" value="16c73ab6-b892-458f-abf5-2f875f74882e"/&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="action" value="Signature Encrypt"/&gt;
+    &lt;parameter name="signaturePropFile" value="crypto.properties" /&gt;
+  &lt;/handler&gt;
+&lt;/requestFlow&gt;
+</source>
+This simple deployment descriptor signs and encrypts the SOAP Body part.
+The only new parameter, <code>signaturePropFile</code>, specifies the
+name of the signature crypto property file to use. Because no 
+<code>encryptionPropFile</code> is declared the handler also uses the signature
+property file to get the encryption certificate. The same holds true for
+the username. The password callback class must return a password
+to get the user's private key (the keystore is defined in the crypto
+property file) that WSS4J uses to generate the signature. The encryption
+method uses the user's public key to encrypt the dynamically generated
+session key.
+</p><p></p><p>
+The <code>action</code> parameter defines <code>Signature Encryption</code>.
+Thus the handler first signs, then the encrypts the data.
+Because the deployment descriptor does not contain specific encryption or 
+signature part parameters, WSS4J defaults to the data of the SOAP Body element.
+</p><p></p><p>
+Also all other parameters use their default setting, such as the format of the
+key identifiers, encryption modifiers, and so on. Please refer to the
+{@link org.apache.ws.security.handler.WSHandlerConstants detailed}
+documentation of the parameters.
+</p><p></p><p>
+If the WSS4J Axis handler shall perform encryption only, then the
+deployment descriptor must contain the encryption specific parameters. Only
+if sign <b>and</b> encryption is required the encryption method falls back to
+the signature parameters if the encryption specific parameters are not set.
+</p><p></p><p>
+The matching receiver deployment descriptor is also very simple:
+<source>
+&lt;requestFlow&gt;
+  &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver"&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="action" value="Signature Encrypt"/&gt;
+    &lt;parameter name="signaturePropFile" value="crypto.properties" /&gt;
+  &lt;/handler&gt;
+ &lt;/requestFlow&gt;	
+</source>
+To reverse the actions, just reverse the action specifiers. The WSS4J
+handler encrypts the SOAP Body first, then signs the encrypted data.
+
+</p></subsection></section><section name="Signing and encrypting multiple XML elements"><p>
+
+Sometimes it is necessary to sign and/or encrypt several parts of a SOAP
+message. The deployment parameters <code>signatureParts</code> and 
+<code>encryptionParts</code> control which SOAP elements to sign or
+to encrypt. Please refer to the
+{@link org.apache.ws.security.handler.WSHandlerConstants#ENCRYPTION_PARTS 
+detailed} description of these parameters.
+</p><p></p><p>
+WSS4J signs or encrypts all declared parts using the same keys, that is 
+the signature or encryption data structures directly reference the 
+specified parts as described in the WSS specifications. The receiver
+automatically detects these references and verfies and decrypts the
+data parts. No special settings in the depolyment descriptor is necessary.
+
+</p></section><section name="Chaining of WSS4J Axis handlers"><p>
+
+This is a very powerful feature that supports even more flexible signature and
+encryption processing such as signatures with multiple keys (overlapping
+signatures), multiple encryption algorithms, or different SOAP actor (role)
+defintions of the security headers.
+
+</p><subsection name="Deployment at the client"><p>
+A deployment descriptor to chain handlers:
+<source>
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;
+    &lt;parameter name="action" value="Signature NoSerialization"/&gt;
+    &lt;parameter name="user" value="firstUser"/&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="signaturePropFile" value="crypto.properties" /&gt;
+    &lt;parameter name="signatureParts" value="{}{http://xmlsoap.org/Ping}ticket" /&gt;    
+   &lt;/handler&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllSender" &gt;
+    &lt;parameter name="action" value="Signature"/&gt;
+    &lt;parameter name="user" value="anotherUser"/&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="signaturePropFile" value="crypto.properties" /&gt;
+   &lt;/handler&gt;  
+  &lt;/requestFlow&gt;
+</source>
+Note the action specifier <code>NoSerialization</code> first handler. 
+In a handler chain of WSS4J handlers every
+but the last handler <i>must</i> have this action specifier. This specifier
+surpresses the very last step of the handler's security processing: the 
+serialization of the processed SOAP request in a XML string (document) that 
+Axis sends to the reveiver. Only the last handler must perform this 
+serialization.
+</p><p></p><p>
+Every handler specification can have its own set of parameters that define
+the individual values for this handler instance. Thus the deployment
+descriptor can define different crypto property files, different usernames,
+and so on. In the example the first handler signs the <code>ticket</code>
+element and the second handler the SOAP Body (default).
+</p><p></p><p>
+Parameters set by the application with <code>setProperty</code> are valid for 
+<b>all</b> handler instances in the handler
+chain (<code>setProperty</code> is defined on the SOAP request (call) level).
+As already decribed, deployment settings overrule application settings. Thus it
+is possible to combine various parameter specifications. A special case is the
+definition of the username. If an application sets the username and one
+handler instance in the chain does not have a <code>user</code> parameter 
+in its deployment part, then this one handler instance uses the username set
+bey the application. After the handler copied the username from the username
+property, the handler sets the property's content to <code>null</code>. 
+Handlers that follow in the chain cannot use this username anymore and 
+must have a user (or encryption user) parameter in their deployment part.
+
+</p></subsection><subsection name="Deployment at the server"><p>
+
+Note: Handler chaining at the receiver side is not yet fully tested.
+</p><p></p><p>
+Handlers at the receiver can only determine different security headers if their
+SOAP actors are different. The WSS4J handler processes each security structure
+inside one security header. Because the security structures contain most
+information to verify or decrypt the SOAP request this constraint is
+not too much of an issue.
+</p><p></p><p>
+Only the password call back class and the <code>Crypto</code> implementation
+(as defined in the crypto property file) must be able to handle all possible 
+certificates, users, passwords, and keys that a security header may contain.
+The following deployment descriptor of a receiver shows this.
+<source>
+  &lt;requestFlow&gt;
+   &lt;handler type="java:org.apache.ws.axis.security.WSDoAllReceiver"&gt;
+    &lt;parameter name="passwordCallbackClass" 
+      value="org.apache.ws.axis.oasis.PWCallback"/&gt;
+    &lt;parameter name="action" value="Signature Signature"/&gt;
+    &lt;parameter name="signaturePropFile" value="crypto.properties" /&gt;
+   &lt;/handler&gt;
+  &lt;/requestFlow&gt;
+</source>
+The client uses two handlers in a chain, each signing a part of the SOAP 
+request but with different certificates. Because the handlers do not 
+specifiy a SOAP actor WSS4J puts both signatures in the security header
+of the default actor. 
+To match the security actions the deployment descriptor of the receiver needs 
+to contain the action declaration <code>Signature Signature</code>. This 
+instructs the WSS4J handler to accept and verify two distinct signatures 
+contained in one security header. Because the signatures use different 
+certificates the <code>Crypto</code> implementation must be able to handle
+these certificates.
+</p><p></p><p>
+Similar requirements are true for the password callback implementation if the
+sender uses handler chaining and uses different encryption parameters in the
+same security header.
+</p><p></p><p>
+If it is necessary to have different parameters for the distinct signature or
+decryption data then these should be put in different security headers. The 
+easiest way to do this is to define different <code>actor</code> parameters
+for each handler in a WSS4J handler chain.
+ 
+</p></subsection></section><section name="Reporting Security results to services/applications"><p>
+The WSS4J <code>WSSecurityEngine</code> processes the security elements inside
+a security header. If something goes wrong, for example a signature 
+verfication fails, then the engine throws a fault. If the security engine
+could perform all operations sucessfully it returns a data structure
+that contains the results of the performed security actions. This data
+structure holds information about the performed action, the usernames or
+identifier in case the security engine performed signature or username token
+processing. Please refer to the
+{@link org.apache.ws.security.WSSecurityEngineResult result} structure.
+</p><p></p><p>
+The <code>WSDoAllReceiver</code> WSS4J handler takes this structure and
+checks if all required actions were performed. If this check fails, the
+WSS4J handler aborts the SOAP request and throws an Axis SOAP fault.
+Otherwise it creates its own data structure 
+{@link org.apache.ws.axis.security.WSDoAllReceiverResult}, copies the
+security results in this structure, and adds the actor name of the
+security header. The it stores this new data structure in a vector and stores
+this vector in a specific 
+{@link org.apache.ws.security.handler.WSHandlerConstants#RECV_RESULTS property} 
+of the current message context. If WSS4J handlers are
+chained, then every handler in the chain adds its result to the vector. The
+vector contains the results in handler-chain order.
+</p><p></p><p>
+This code snippet shows how a Axis service can access the security result
+data:
+<source>
+    public void ping(javax.xml.rpc.holders.StringHolder text,
+        org.apache.ws.axis.oasis.ping.TicketType ticket)
+        throws java.rmi.RemoteException {
+
+        text.value = "Echo " + text.value.trim();
+		
+        // get the message context first
+        MessageContext msgContext = MessageContext.getCurrentContext();
+        Message reqMsg = msgContext.getRequestMessage();
+
+        Vector results = null;
+        // get the result Vector from the property
+        if ((results =
+            (Vector) msgContext.getProperty(WSHandlerConstants.RECV_RESULTS))
+             == null) {
+            System.out.println("No security results!!");
+        }
+        System.out.println("Number of results: " + results.size());
+        for (int i = 0; i &lt; results.size(); i++) {
+            WSHandlerResult hResult = (WSHandlerResult)results.get(i);
+            String actor = hResult.getActor();
+            Vector hResults = hResult.getResults();
+            for (int j = 0; j &lt; hResults.size(); j++) {
+              	WSSecurityEngineResult eResult = (WSSecurityEngineResult) hResults.get(j);
+                // Note: an encryption action does not have an associated principal
+    	        // only Signature and UsernameToken actions return a principal
+                if (eResult.getAction() != WSConstants.ENCR) {
+                    System.out.println(eResult.getPrincipal().getName());
+                }
+            }
+        }
+    }
+</source>
+The principal structure is either a 
+{@link org.apache.ws.security.WSUsernameTokenPrincipal UsernameToken} principal 
+or a {@link java.security.Principal X509Principal}. The 
+princpals contain the names plus other information of the verified username
+token or signature certificate.
+ 
+</p></section><section name="Some hints"><subsection name="Client"><p>
+At the client side, the WSS4J Axis handler, as all other parts of Axis, run
+in the context of the calling application. Depending on the application,
+the callback classes may perform complex operations, even do some user 
+interaction, to get the password or to access some database to get 
+certificates or keys. There are no timeouts defined at the client side 
+before the SOAP request is put on the wire.
+
+</p></subsection><subsection name="Server"><p>
+On the server side the WSS4J handler run in the same context as the other part
+of the server, usually some servlet container, such as Tomcat. Also the server
+must be able to handle many requests in a short time. Thus the password 
+callback as well as the <code>Crypto</code> implementation shall be
+as fast as possible. In general, no user interaction is possible at the
+server side to gather passwords. Also at this point of the SOAP request
+processing there are active timeouts, even if they are fairly long.
+
+</p></subsection><subsection name="Bi-directional SOAP Security"><p>
+WSS4J fully supports bi-directional SOAP security. To enable bi-directional
+support just put <code>WSDoAllSender</code> on the 
+<code>responseFlow</code> at the server and <code>WSDoAllReceiver</code>
+at the response flow of the client thus reversing the roles. Similar to
+the above hints, the server side part (now <code>WSDoAllSender</code>)
+runs in the server context and <code>WSDoAllReceiver</code>
+runs in the application (client) context. There are no Axis timeout
+constraints on the client side after Axis received the response 
+and handed it over to the WSS4J handler.
+
+</p></subsection><subsection name="Handler chaining"><p>
+Usually WSS4J handlers are chained without any other handler between them in
+the chain. It is, however, possible to do so. In this case the intermediate
+handler <b>must not</b> modify the SOAP Envelope that is contained in the
+Axis message. This could (most probably will) invalidate or destroy any 
+security actions done sofar. Such an intermediate handler may set some 
+properties that may influence the processing of the following WSS4J handler, 
+such as setting a new username, password callback class, and so on.
+
+<!-- Put @see and @since tags down here. -->
+@since WSS4J 1.0</p></subsection></section></body></document>
\ No newline at end of file
diff --git a/xdocs/stylesheets/maven.css b/xdocs/stylesheets/maven.css
new file mode 100644
index 0000000..6addb4c
--- /dev/null
+++ b/xdocs/stylesheets/maven.css
@@ -0,0 +1,114 @@
+body {
+ background: #fff;
+ color: #000;
+ }
+
+.app h3 {
+ color: #fff;
+ background-color: #036;
+ }
+
+.app h4 {
+ color: #fff;
+ background-color: #888;
+ }
+
+.a td { 
+ background: #ddd;
+ color: #000;
+ }
+
+.b td { 
+ background: #efefef;
+ color: #000;
+ }
+
+.app th {
+ background-color: #bbb;
+ color: #fff;
+ }
+
+div#banner {
+ border-top: 1px solid #369;
+ border-bottom: 1px solid #003;
+ }
+
+#banner, #banner td { 
+ background: #036;
+ color: #fff;
+ }
+
+#leftcol {
+ background: #eee;
+ color: #000;
+ border-right: 1px solid #aaa;
+ border-bottom: 1px solid #aaa;
+ border-top: 1px solid #fff;
+}
+
+#navcolumn {
+ background: #eee;
+ color: #000;
+ border-right: none;
+ border-bottom: none;
+ border-top: none;
+ }
+
+#breadcrumbs {
+ background-color: #ddd;
+ color: #000;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #aaa;
+ }
+
+#source {
+ background-color: #fff;
+ color: #000;
+ border-right: 1px solid #888; 
+ border-left: 1px solid #888; 
+ border-top: 1px solid #888; 
+ border-bottom: 1px solid #888; 
+ margin-right: 7px;
+ margin-left: 7px;
+ margin-top: 1em;
+ }
+
+#source pre {
+ margin-right: 7px;
+ margin-left: 7px;
+ }
+
+a[name]:hover, #leftcol a[name]:hover {
+ color: inherit !important;
+ }
+
+a:link, #breadcrumbs a:visited, #navcolumn a:visited, .app a:visited, .tasknav a:visited {
+ color: blue;
+ }
+
+a:active, a:hover, #leftcol a:active, #leftcol a:hover {
+ color: #f30 !important;
+ }
+
+a:link.selfref, a:visited.selfref {
+ color: #555 !important;
+ }
+
+h3, h4 {
+ margin-top: 1em;
+ margin-bottom: 0;
+ }
+
+img.handle {
+ border: 0;
+ padding-right: 2px;
+}
+
+#navcolumn div div  {
+ background-image: none;
+ background-repeat: no-repeat;
+}
+
+#navcolumn div div {
+  padding-left: 10px;
+}