From 7252c1c1dba0b7ad4b2e692169da526491994aab Mon Sep 17 00:00:00 2001
From: Christophe Sovant <christophe.sovant@forgerock.com>
Date: Fri, 11 Sep 2009 14:48:00 +0000
Subject: [PATCH] Improvements in ant build + update STAF/services versions + dynamic dsmlService compilation/loading

---
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/DSMLService.java                 |  485 ++++++++
 opendj-sdk/opends/tests/staf-tests/shared/ant/staf.xml                                                          |  237 ++-
 opendj-sdk/opends/tests/staf-tests/shared/staf/staf-controller.cfg                                              |   30 
 opendj-sdk/opends/tests/staf-tests/shared/dsml/MANIFEST.MF                                                      |    5 
 opendj-sdk/opends/tests/staf-tests/shared/ant/dependencies.xml                                                  |   66 
 opendj-sdk/opends/tests/staf-tests/shared/ant/opends.xml                                                        |   46 
 opendj-sdk/opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_setup.xml                               |  118 ++
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/JAXBCheckerException.java |   36 
 /dev/null                                                                                                       |    0 
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/Checker.java              |  235 ++++
 opendj-sdk/opends/tests/staf-tests/shared/functions/stafcmd.xml                                                 |  226 +++
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/ResponseChecker.java      |  152 ++
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/DsmlAttrCompare.java      |   40 
 opendj-sdk/opends/tests/staf-tests/shared/ant/build.properties                                                  |   44 
 opendj-sdk/opends/tests/staf-tests/shared/ant/tests.xml                                                         |   12 
 opendj-sdk/opends/tests/staf-tests/shared/functions/utils.xml                                                   |  110 +
 opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/LDAPResultCode.java       |  810 +++++++++++++
 opendj-sdk/opends/tests/staf-tests/shared/functions/webcontainer.xml                                            |    8 
 opendj-sdk/opends/tests/staf-tests/shared/stax.dtd                                                              |  735 ++++++------
 opendj-sdk/opends/tests/staf-tests/shared/ant/build.xml                                                         |   43 
 opendj-sdk/opends/tests/staf-tests/shared/tests/config.py.stubs                                                 |    3 
 21 files changed, 2,869 insertions(+), 572 deletions(-)

diff --git a/opendj-sdk/opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_setup.xml b/opendj-sdk/opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_setup.xml
index 3285df9..134763a 100755
--- a/opendj-sdk/opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_setup.xml
+++ b/opendj-sdk/opends/tests/staf-tests/functional-tests/testcases/dsml/dsml_setup.xml
@@ -42,6 +42,124 @@
               #@TestPostamble       none
               #@TestResult          Success if  returns 0.
           -->
+          <testcase name="getTestCaseName('prepare DSML STAF service')">
+            <sequence>
+              <call function="'testCase_Preamble'"/>
+
+              <call function="'createFolder'">
+                {
+                'location'   : STAXServiceMachine,
+                'foldername' : '%s/dsml/STAF-INF/jars' % TMPDIR
+                }
+              </call>
+
+              <call function="'unZipFile'">
+                {
+                'location' : STAXServiceMachine,
+                'zipfile'  : '%s/%s' % (ZIPPATH, ZIPNAME),
+                'file'     : '%s/lib/OpenDS.jar' % OPENDSNAME,
+                'unzipdir' : '%s/dsml' % TMPDIR
+                }
+              </call>
+
+              <call function="'copyFile'">
+                {
+                'location'   : STAXServiceMachine,
+                'srcfile'    : '%s/dsml/%s/lib/OpenDS.jar' % (TMPDIR,OPENDSNAME),
+                'destfile'   : '%s/dsml/STAF-INF/jars/OpenDS.jar' % TMPDIR,
+                'remotehost' : STAXServiceMachine
+                }
+              </call>
+
+              <call function="'unZipFile'">
+                {
+                'location' : STAXServiceMachine,
+                'zipfile'  : DSML_WARPATH,
+                'directory': 'WEB-INF/classes',
+                'unzipdir' : '%s/dsml' % TMPDIR,
+                }
+              </call>
+
+              <call function="'copyFolder'">
+                {
+                'location'   : STAXServiceMachine,
+                'srcfolder'  : '%s/dsml/WEB-INF/classes' % TMPDIR,
+                'destfolder' : '%s/dsml/STAF-INF/classes' % TMPDIR,
+                'remotehost' : STAXServiceMachine
+                }
+              </call>
+
+              <script>
+                if is_windows_platform(STAXServiceMachine):
+                  separator=';'
+                else:
+                  separator=':'
+
+                opendsjar='%s/dsml/STAF-INF/jars/OpenDS.jar' % TMPDIR
+                dsmlclasses='%s/dsml/STAF-INF/classes' % TMPDIR
+              </script>
+
+              <call function="'GetVar'">
+                {
+                'location'  : STAXServiceMachine,
+                'type'      : 'system',
+                'variable'  : 'STAF/Env/CLASSPATH'
+                }
+              </call>
+              <script>
+                cp=STAFResult
+              </script>
+
+              <call function="'compileJava'" >
+                {
+                'location'   : STAXServiceMachine,
+                'foldername' : '%s/src' % TESTS_DSML_DIR,
+                'destfolder' : '%s/dsml/STAF-INF/classes' % TMPDIR,
+                'classpath'  : '%s%s%s%s%s' \
+                               % (opendsjar,separator,dsmlclasses,separator,cp)
+                }
+              </call>
+
+              <call function="'createFolder'">
+                {
+                'location'   : location,
+                'foldername' : '%s/dsml' % local.java
+                }
+              </call>
+              <call function="'createJar'" >
+                {
+                'location'     : STAXServiceMachine,
+                'jarname'      : '%s/dsml/dsmlService.jar' % local.java,
+                'entrypoint'   : 'STAF-INF',
+                'pathfolder'   : '%s/dsml' % TMPDIR,
+                'manifestpath' : '%s/MANIFEST.MF' % TESTS_DSML_DIR
+                }
+              </call>
+
+              <call function="'addSTAFJavaService'" >
+                {
+                'location'    : STAXServiceMachine,
+                'serviceName' : 'Dsml',
+                'serviceJar'  : '%s/dsml/dsmlService.jar' % local.java,
+                'J2'          : '-Xms128m -Xmx512m'
+                }
+              </call>
+
+              <call function="'testCase_Postamble'"/>
+            </sequence>
+          </testcase>
+
+          <!--- Test Case information
+              #@TestMarker          setup
+              #@TestName            setup: prepare DSML directory server
+              #@TestIssue           none
+              #@TestPurpose         Prepare the directory server necessary to the
+                                    test suite.
+              #@TestPreamble        none
+              #@TestStep            prepare dsml directory server instance
+              #@TestPostamble       none
+              #@TestResult          Success if  returns 0.
+          -->
           <testcase name="getTestCaseName('prepare DSML Directory backend')">
             <sequence>
               <call function="'testCase_Preamble'"/>
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/build.properties b/opendj-sdk/opends/tests/staf-tests/shared/ant/build.properties
index 612737c..5f73466 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/build.properties
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/build.properties
@@ -24,10 +24,6 @@
 #      Copyright 2007-2009 Sun Microsystems, Inc.
 
 
-# Shared folder
-shared.dir=${basedir}/shared
-
-
 ######
 ## These values can be overrided using the user.properties file
 ######
@@ -35,36 +31,17 @@
 # Repository section
 repository.dir=${basedir}/temp/repository
 
-# STAF section
-staf.install.dir=${repository.dir}/install/staf-${os.myname}
-staf.config.dir=${repository.dir}/configs
-staf.shared.dir=${shared.dir}/staf
-staf.config.stubs=${staf.shared.dir}/staf-${staf.type}.cfg
-staf.config.file=${staf.config.dir}/staf-${staf.type}-${host.name}.cfg
-staf.bin.dir=${staf.install.dir}/bin
-staf.daemon=${staf.bin.dir}/STAFProc${extension.binary}
-staf.executable=${staf.bin.dir}/STAF${extension.binary}
-
 # Archives section
-archives.dir=${repository.dir}/archives
 staf.default=true
 staf.url=http://superb-east.dl.sourceforge.net/sourceforge/staf
-staf.version=332
+staf.version=334
 staf.port=6500
-## staf.archive value depends on os
-stax.version=335
-stax.archive=STAXV${stax.version}.zip
+stax.version=337
 email.version=332
-email.archive=EmailV${email.version}.zip
-event.version=312
-event.archive=EventV${event.version}.zip
-eventmanager.version=334
-eventmanager.archive=EventManagerV${eventmanager.version}.zip
+event.version=313
+eventmanager.version=335
 http.version=301
-http.archive=HTTPV${http.version}.zip
 tomcat.version=6.0.20
-tomcat.url=http://archive.apache.org/dist/tomcat/tomcat-6/v${tomcat.version}/bin
-tomcat.archive=apache-tomcat-${tomcat.version}.zip
 
 # Proxy section
 proxy.enabled=false
@@ -84,6 +61,9 @@
 ## These values can be overrided using the tests-XXX-XXX.properties file
 ######
 
+# Shared folder
+shared.dir=${basedir}/shared
+
 # Hostname section
 local.hostname=${host.name}
 remote.hostname=${host.name}
@@ -103,24 +83,28 @@
 local.javahome=${java.home}/..
 remote.javahome=${java.home}/..
 
+# STAF section
+staf.shared.dir=${shared.dir}/staf
+staf.config.stubs=${staf.shared.dir}/staf-${staf.type}.cfg
+
 # Tests section
 tests.default=true
 tests.dir=${basedir}/${tests.type}
 tests.shared.dir=${shared.dir}/tests
 tests.config.stubs=${tests.shared.dir}/config.py.stubs
 tests.topology.dir=${shared.dir}/topology
-tests.run.dir=${logs.dir}/${tests.type}/run
-tests.tmp.dir=${logs.dir}/${tests.type}/tmp
 tests.xml=${tests.shared.dir}/runTestJob.xml
 opends.port.ldap=1389
 opends.port.admin=4444
 opends.port.ldaps=1636
 opends.admin.dn=cn=myself
 opends.admin.pwd=password
+replication.split=false
 snmp.opendmk.lib.dir=
 ldclt.dir=
+temp.dir=/tmp
 test.plan.custom=
-test.plan.functional.default=aci,backends,clu,core,dsconfig,dsml,groups,i18n,indexes,logging,monitoring,plugins,privileges,replication,schema,security,setup,snmp,tasks,virtualAttributes
+test.plan.functional.default=aci,backends,clu,clu_secure,core,dsconfig,dsml,groups,i18n,indexes,logging,monitoring,plugins,privileges,replication,schema,security,setup,snmp,tasks,virtualAttributes
 test.plan.stress.default=ldap_operation,import_ldif
 verbose.mode=false
 logs.uri=file://
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/build.xml b/opendj-sdk/opends/tests/staf-tests/shared/ant/build.xml
index 0460e42..bb8c320 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/build.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/build.xml
@@ -192,7 +192,7 @@
       </else>
     </if>
 
-    <!-- Set value for tests.config.file variable -->
+    <!-- Set value for tests.config.file variable depending on tests.mode -->
     <if>
       <equals arg1="${tests.mode}" arg2="remote"/>
       <then>
@@ -203,17 +203,7 @@
       </else>
     </if>
 
-    <!-- Set value for tests.run.dir variable -->
-    <if>
-      <not>
-        <equals arg1="${logs.dir}" arg2="${basedir}/temp/logs"/>
-      </not>
-      <then>
-        <var name="tests.run.dir" value="${logs.dir}/${tests.type}/run"/>
-      </then>
-    </if>
-
-    <!-- Set value for email.subject variable -->
+    <!-- Set value for email.subject variable depending on tests.type -->
     <if>
       <equals arg1="${tests.type}" arg2="functional-tests"/>
       <then>
@@ -226,23 +216,46 @@
       </else>
     </if>
 
+    <!-- Set value for variables which depends on user configuration -->
+    <var name="staf.name" value="STAF-v${staf.version}-${os.myname}"/>
+    <var name="staf.install.dir" value="${repository.dir}/install"/>
+    <var name="staf.config.dir" value="${repository.dir}/configs"/>
+    <var name="staf.config.file" value="${staf.config.dir}/staf-${staf.type}-${host.name}.cfg"/>
+    <var name="staf.bin.dir" value="${staf.install.dir}/${staf.name}/bin"/>
+    <var name="staf.daemon" value="${staf.bin.dir}/STAFProc${extension.binary}"/>
+    <var name="staf.executable" value="${staf.bin.dir}/STAF${extension.binary}"/>
 
-    <!-- Set value for staf.archive and staf.lib.dir variables -->
+    <var name="archives.dir" value="${repository.dir}/archives"/>
+    <var name="tests.run.dir" value="${logs.dir}/${tests.type}/run"/>
+    <var name="tests.tmp.dir" value="${logs.dir}/${tests.type}/tmp"/>
+
     <if>
       <equals arg1="${os.family}" arg2="windows"/>
       <then>
         <!-- Windows system -->
         <property name="staf.archive"
                   value="STAF${staf.version}-setup-${os.myname}.exe"/>
-        <property name="staf.lib.dir" value="${staf.install.dir}${file.separator}bin"/>
+        <property name="staf.lib.dir" value="${staf.install.dir}/${staf.name}/bin"/>
       </then>
       <else>
         <!-- Other systems -->
         <property name="staf.archive"
                   value="STAF${staf.version}-${os.myname}.tar.gz"/>
-        <property name="staf.lib.dir" value="${staf.install.dir}${file.separator}lib"/>
+        <property name="staf.lib.dir" value="${staf.install.dir}/${staf.name}/lib"/>
       </else>
     </if>
+    <var name="stax.name" value="STAX-v${stax.version}"/>
+    <var name="stax.archive" value="STAXV${stax.version}.zip"/>
+    <var name="email.name" value="Email-v${email.version}"/>
+    <var name="email.archive" value="EmailV${email.version}.zip"/>
+    <var name="event.name" value="Event-v${event.version}"/>
+    <var name="event.archive" value="EventV${event.version}.zip"/>
+    <var name="eventmanager.name" value="EventManager-v${eventmanager.version}"/>
+    <var name="eventmanager.archive" value="EventManagerV${eventmanager.version}.zip"/>
+    <var name="http.name" value="HTTP-v${http.version}"/>
+    <var name="http.archive" value="HTTPV${http.version}.zip"/>
+    <var name="tomcat.url" value="http://archive.apache.org/dist/tomcat/tomcat-6/v${tomcat.version}/bin"/>
+    <var name="tomcat.archive" value="apache-tomcat-${tomcat.version}.zip"/>
   </target>
 
   <!-- ######### -->
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/dependencies.xml b/opendj-sdk/opends/tests/staf-tests/shared/ant/dependencies.xml
index 7589a97..2cb2684 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/dependencies.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/dependencies.xml
@@ -44,47 +44,39 @@
         <var name="ext" unset="true"/>
         <var name="url" unset="true"/>
 
-        <if>
-          <not>
-            <available file="${staf.install.dir}/bin/STAF.cfg"/>
-          </not>
-          <then>
-            <trycatch property="error" reference="referror">
-              <try>
-                <propertyregex property="ext"
-                               input="@{archive}"
-                               regexp=".*\.(.*)"
-                               select="\1"
-                               casesensitive="false"/>
+        <trycatch property="error" reference="referror">
+          <try>
+            <propertyregex property="ext"
+                           input="@{archive}"
+                           regexp=".*\.(.*)"
+                           select="\1"
+                           casesensitive="false"/>
 
-                <echo>Checking @{archive} archive...</echo>
-                <switch value="${ext}">
-                  <case value="gz">
-                    <!-- gz files -->
-                    <gunzip src="${archives.dir}/@{archive}"
-                            dest="${tmp.dir}"/>
-                  </case>
-                  <case value="zip">
-                    <!-- zip files -->
-                    <unzip src="${archives.dir}/@{archive}"
-                           dest="${tmp.dir}"/>
-                  </case>
-                  <default>
-                  </default>
-                </switch>
+            <echo>Checking @{archive} archive...</echo>
+            <switch value="${ext}">
+              <case value="gz">
+                <!-- gz files -->
+                <gunzip src="${archives.dir}/@{archive}"
+                        dest="${tmp.dir}"/>
+              </case>
+              <case value="zip">
+                <!-- zip files -->
+                <unzip src="${archives.dir}/@{archive}"
+                       dest="${tmp.dir}"/>
+              </case>
+              <default>
+              </default>
+            </switch>
 
-                <var name="rc" value="0"/>
-              </try>
+            <var name="rc" value="0"/>
+          </try>
 
-              <catch>
-                <echo>ERROR: ${error}</echo>
-                <var name="rc" value="-1"/>
-              </catch>
-            </trycatch>
-          </then>
-        </if>
+          <catch>
+            <echo>ERROR: ${error}</echo>
+            <var name="rc" value="-1"/>
+          </catch>
+        </trycatch>
 
-        <var name="rc" value="0"/>
         <if>
           <or>
             <not>
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/opends.xml b/opendj-sdk/opends/tests/staf-tests/shared/ant/opends.xml
index ca3434e..dc8cf44 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/opends.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/opends.xml
@@ -60,10 +60,25 @@
               </and>
               <then>
                 <echo>Build ${opends.name} with SNMP</echo>
-                <replace file="${project.home}/build.properties"
-                         value="opendmk.lib.dir=${snmp.opendmk.lib.dir}">
-                  <replacefilter token="opendmk.lib.dir="/>
-                </replace>
+                <var file="${basedir}/user.properties"/>
+                <if>
+                    <or>
+                      <equals arg1="${opendmk.lib.dir}" arg2=""/>
+                      <not>
+                        <equals arg1="${opendmk.lib.dir}" arg2="${snmp.opendmk.lib.dir}"/>
+                      </not>
+                    </or>
+                    <then>
+                      <replace file="${project.home}/build.properties"
+                               value="opendmk.lib.dir=">
+                        <replacefilter token="opendmk.lib.dir=${opendmk.lib.dir}"/>
+                      </replace>
+                      <replace file="${project.home}/build.properties"
+                               value="opendmk.lib.dir=${snmp.opendmk.lib.dir}">
+                        <replacefilter token="opendmk.lib.dir="/>
+                      </replace>
+                    </then>
+                </if>
                 <property name="package.rebuild" value="true"/>
               </then>
               <else>
@@ -83,10 +98,25 @@
               </and>
               <then>
                 <echo>Rebuild ${opends.name} with SNMP</echo>
-                <replace file="${project.home}/build.properties"
-                         value="opendmk.lib.dir=${snmp.opendmk.lib.dir}">
-                  <replacefilter token="opendmk.lib.dir="/>
-                </replace>
+                <var file="${basedir}/user.properties"/>
+                <if>
+                    <or>
+                      <equals arg1="${opendmk.lib.dir}" arg2=""/>
+                      <not>
+                        <equals arg1="${opendmk.lib.dir}" arg2="${snmp.opendmk.lib.dir}"/>
+                      </not>
+                    </or>
+                    <then>
+                      <replace file="${project.home}/build.properties"
+                               value="opendmk.lib.dir=">
+                        <replacefilter token="opendmk.lib.dir=${opendmk.lib.dir}"/>
+                      </replace>
+                      <replace file="${project.home}/build.properties"
+                               value="opendmk.lib.dir=${snmp.opendmk.lib.dir}">
+                        <replacefilter token="opendmk.lib.dir="/>
+                      </replace>
+                    </then>
+                </if>
                 <property name="package.rebuild" value="true"/>
               </then>
             </if>
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/staf.xml b/opendj-sdk/opends/tests/staf-tests/shared/ant/staf.xml
index 2b00bb8..c0a61a7 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/staf.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/staf.xml
@@ -34,69 +34,122 @@
   <target name="install">
     <if>
       <not>
-        <available file="${staf.install.dir}/bin/STAF.cfg"/>
+        <available file="${staf.install.dir}/${staf.name}/bin/STAF.cfg"/>
       </not>
       <then>
         <mkdir dir="${tmp.dir}"/>
 
         <!-- Install STAF -->
         <echo>Installing staf, please wait...</echo>
-        <mkdir dir="${staf.install.dir}"/>
-        <gunzip src="${archives.dir}/${staf.archive}" dest="${tmp.dir}"/>
-        <untar dest="${tmp.dir}">
-          <fileset dir="${tmp.dir}">
-            <include name="*.tar"/>
-          </fileset>
-        </untar>
-        <chmod file="${tmp.dir}/staf/STAFInst" perm="755"/>
-        <exec executable="${tmp.dir}/staf/STAFInst">
-          <arg value="-source"/>
-          <arg value="${tmp.dir}/staf"/>
-          <arg value="-target"/>
-          <arg value="${staf.install.dir}"/>
-          <arg value="-acceptlicense"/>
-        </exec>
-        <delete dir="${repository.dir}/staf"/>
+        <mkdir dir="${staf.install.dir}/${staf.name}"/>
+        <if>
+          <equals arg1="${os.family}" arg2="windows"/>
+          <then>
+            <exec executable="${archives.dir}/${staf.archive}"
+                  resultproperty="rc">
+              <arg value="-i"/>
+              <arg value="silent"/>
+              <arg value="-DACCEPT_LICENSE=1"/>
+              <arg value="-DUSER_INSTALL_DIR=${staf.install.dir}/${staf.name}"/>
+              <arg value="-DREGISTER=0"/>
+              <arg value="-DUPDATE_ENVIRONMENT=User"/>
+              <arg value="-DSTART_ON_LOGIN=0"/>
+              <arg value="-DSCREATE_START_MENU_ICONS=0"/>
+            </exec>
+          </then>
+          <else>
+            <gunzip src="${archives.dir}/${staf.archive}" dest="${tmp.dir}"/>
+            <untar dest="${tmp.dir}">
+              <fileset dir="${tmp.dir}">
+                <include name="*.tar"/>
+              </fileset>
+            </untar>
+            <chmod file="${tmp.dir}/staf/STAFInst" perm="755"/>
+            <exec executable="${tmp.dir}/staf/STAFInst"
+                  resultproperty="rc">
+              <arg value="-source"/>
+              <arg value="${tmp.dir}/staf"/>
+              <arg value="-target"/>
+              <arg value="${staf.install.dir}/${staf.name}"/>
+              <arg value="-acceptlicense"/>
+            </exec>
+            <delete dir="${repository.dir}/staf"/>
+          </else>
+        </if>
 
-        <!-- Install services -->
-        <echo>Installing services, please wait...</echo>
-        <mkdir dir="${staf.install.dir}/services"/>
-        <unzip src="${archives.dir}/${email.archive}"
-           dest="${staf.install.dir}/services"/>
-        <unzip src="${archives.dir}/${event.archive}"
-           dest="${staf.install.dir}/services"/>
-        <unzip src="${archives.dir}/${eventmanager.archive}"
-           dest="${staf.install.dir}/services"/>
-        <unzip src="${archives.dir}/${stax.archive}"
-           dest="${staf.install.dir}/services"/>
-        <unzip src="${archives.dir}/${http.archive}"
-           dest="${staf.install.dir}/services"/>
-
-        <!-- Add DSML service extension -->
-        <mkdir dir="${staf.install.dir}/services/DSML"/>
-        <copy todir="${staf.install.dir}/services/DSML">
-          <fileset dir="${basedir}/../staf-tests/shared/dsml"
-               includes="dsmlService.jar"/>
-        </copy>
-
-        <delete includeemptydirs="true">
-          <fileset dir="${tmp.dir}" includes="**/*"/>
-        </delete>
+        <fail message="STAF installation failed">
+          <condition>
+            <and>
+              <not>
+                <equals arg1="${rc}" arg2="0"/>
+              </not>
+            </and>
+          </condition>
+        </fail>
       </then>
       <else>
-        <echo>Staf is already installed in [${staf.install.dir}]</echo>
+        <echo>Staf is already installed in [${staf.install.dir}/${staf.name}]</echo>
       </else>
     </if>
+
+    <!-- Install services -->
+    <echo>Installing services, please wait...</echo>
+    <var name="list" value="${stax.archive},${email.archive}"/>
+    <var name="list" value="${list},${event.archive},${eventmanager.archive}"/>
+    <var name="list" value="${list},${http.archive}"/>
+    <for list="${list}" param="archive">
+      <sequential>
+        <var name="name" unset="true"/>
+
+        <propertyregex property="name"
+                       input="@{archive}"
+                       regexp="(.*)V(.*)\..*"
+                       select="\1-v\2"
+                       casesensitive="true"/>
+
+        <if>
+          <not>
+            <available file="${staf.install.dir}/${name}"/>
+          </not>
+          <then>
+            <unzip src="${archives.dir}/@{archive}"
+                   dest="${staf.install.dir}">
+              <chainedmapper>
+                <flattenmapper/>
+                  <globmapper from="*" to="${name}/*"/>
+                  <mapper>
+                    <globmapper from="*" to="*"/>
+                  </mapper>
+                </chainedmapper>
+            </unzip>
+          </then>
+          <else>
+            <echo>${name} is already installed in [${staf.install.dir}/${name}]</echo>
+          </else>
+        </if>
+      </sequential>
+    </for>
+
+    <!-- Add DSML service extension -->
+    <mkdir dir="${staf.install.dir}/DSML"/>
+    <copy todir="${staf.install.dir}/DSML">
+      <fileset dir="${basedir}/../staf-tests/shared/dsml"
+               includes="dsmlService.jar"/>
+    </copy>
+
+    <delete includeemptydirs="true">
+      <fileset dir="${tmp.dir}" includes="**/*"/>
+    </delete>
   </target>
 
   <!-- Uninstall STAF and services -->
   <target name="uninstall">
     <if>
-      <available file="${staf.install.dir}/bin/STAF.cfg"/>
+      <available file="${staf.install.dir}/${staf.name}/bin/STAF.cfg"/>
       <then>
         <echo>Uninstalling staf, please wait...</echo>
-        <exec executable="${staf.install.dir}/STAFUninst"/>
-        <delete dir="${staf.install.dir}"/>
+        <exec executable="${staf.install.dir}/${staf.name}/STAFUninst"/>
+        <delete dir="${staf.install.dir}/${staf.name}"/>
       </then>
       <else>
         <echo>Staf is not installed</echo>
@@ -108,7 +161,7 @@
   <target name="start">
     <!-- Copy staf.cfg -->
     <mkdir dir="${staf.config.dir}"/>
-    <copy file="${staf.config.stubs}" tofile="${staf.config.file}">
+    <copy file="${staf.config.stubs}" tofile="${staf.config.file}" overwrite="true">
       <filterchain>
         <expandproperties/>
       </filterchain>
@@ -119,17 +172,17 @@
         <socket port="${staf.port}" server="${host.name}"/>
       </not>
       <then>
-        <delete dir="${staf.install.dir}/logs"/>
-        
+        <var name="cp" value="${project.home}/resource/dsml/lib/activation.jar:${project.home}/resource/dsml/lib/j2ee.jar:${project.home}/resource/dsml/lib/jaxb-api.jar:${project.home}/resource/dsml/lib/jaxb-impl.jar:${project.home}/resource/dsml/lib/jaxb-xjc.jar:${project.home}/resource/dsml/lib/jaxb1-impl.jar:${project.home}/resource/dsml/lib/jsr173_1.0_api.jar:${project.home}/resource/dsml/lib/saaj-1.3.jar:${project.home}/resource/dsml/lib/saaj-impl-1.3.jar"/>
+
         <echo>Starting staf, please wait...</echo>
         <exec dir="${staf.bin.dir}"
               executable="${staf.daemon}"
               spawn="true">
           <arg value="${staf.config.file}"/>
-          <env key="${var.path}" path="${java.path}${file.separator}bin${path.separator}${staf.install.dir}${file.separator}bin"/>
-          <env key="LD_LIBRARY_PATH" path="${staf.install.dir}/lib"/>
-          <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar${path.separator}:${project.home}/ext/svnkit/svnkit.jar:."/>
-          <env key="STAFCONVDIR" value="${staf.install.dir}/codepage"/>
+          <env key="${var.path}" path="${java.path}/bin:${staf.install.dir}/${staf.name}/bin"/>
+          <env key="LD_LIBRARY_PATH" path="${staf.lib.dir}"/>
+          <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar:${project.home}/ext/svnkit/svnkit.jar:${cp}:."/>
+          <env key="STAFCONVDIR" value="${staf.install.dir}/${staf.name}/codepage"/>
           <env key="LANG" value="en_US.ISO8859-1"/>
           <env key="LC_ALL" value="en_US.ISO8859-1"/>
           <env key="STAFCODEPAGE" value="LATIN_1"/>
@@ -137,7 +190,7 @@
         </exec>
 
         <echo>Waiting for service to become available...</echo>
-        <waitfor maxwait="3"
+        <waitfor maxwait="1"
              maxwaitunit="minute"
              checkevery="10"
              checkeveryunit="second"
@@ -145,7 +198,15 @@
           <socket server="${host.name}" port="${staf.port}"/>
         </waitfor>
 
-        <echo>STAF is now ready to serve requests</echo>
+        <if>
+          <isset property="timeout"/>
+          <then>
+            <fail>"STAF initialisation failed"</fail>
+          </then>
+          <else>
+            <echo>STAF is now ready to serve requests</echo>
+          </else>
+        </if>
       </then>
       <else>
         <echo>Staf is already listening on port [${staf.port}]</echo>
@@ -161,14 +222,14 @@
         <echo>Stopping staf, please wait...</echo>
         <exec executable="${staf.executable}">
           <arg line="local shutdown shutdown"/>
-          <env key="${var.path}" path="${java.path}${file.separator}bin${path.separator}${staf.install.dir}${file.separator}bin"/>
+          <env key="${var.path}" path="${java.path}/bin:${staf.install.dir}/${staf.name}/bin"/>
           <env key="LD_LIBRARY_PATH" path="${staf.lib.dir}"/>
-          <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar${path.separator}:."/>
-          <env key="STAFCONVDIR" value="${staf.install.dir}/codepage"/>
+          <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar:."/>
+          <env key="STAFCONVDIR" value="${staf.install.dir}/${staf.name}/codepage"/>
         </exec>
 
         <echo>Waiting for service to shutdown gracefully...</echo>
-        <waitfor maxwait="3"
+        <waitfor maxwait="1"
              maxwaitunit="minute"
              checkevery="10"
              checkeveryunit="second"
@@ -197,17 +258,14 @@
 
     <echo></echo>
     <if>
-      <available file="${staf.install.dir}/bin/STAF.cfg"/>
+      <available file="${staf.install.dir}/${staf.name}/bin/STAF.cfg"/>
       <then>
-
-        <echo>Staf is installed in [${staf.install.dir}]</echo>
+        <echo>Staf is installed in [${staf.install.dir}/${staf.name}]</echo>
       </then>
       <else>
         <echo>Staf is not installed</echo>
       </else>
     </if>
-
-    <echo></echo>
     <if>
       <socket port="${staf.port}" server="${host.name}"/>
       <then>
@@ -217,32 +275,67 @@
         <echo>Staf is not running</echo>
       </else>
     </if>
+
+    <echo></echo>
+    <var name="list" value="${stax.archive},${email.archive}"/>
+    <var name="list" value="${list},${event.archive},${eventmanager.archive}"/>
+    <var name="list" value="${list},${http.archive}"/>
+    <for list="${list}" param="archive">
+      <sequential>
+        <var name="shortname" unset="true"/>
+        <var name="name" unset="true"/>
+
+        <propertyregex property="shortname"
+                       input="@{archive}"
+                       regexp="(.*)V.*\..*"
+                       select="\1"
+                       casesensitive="true"/>
+
+        <propertyregex property="name"
+                       input="@{archive}"
+                       regexp="(.*)V(.*)\..*"
+                       select="\1-v\2"
+                       casesensitive="true"/>
+
+        <if>
+          <not>
+            <available file="${staf.install.dir}/${name}"/>
+          </not>
+          <then>
+            <echo>${shortname} is not installed</echo>
+          </then>
+          <else>
+            <echo>${shortname} is installed in [${staf.install.dir}/${name}]</echo>
+          </else>
+        </if>
+      </sequential>
+    </for>
   </target>
 
   <!-- Display STAF gui -->
   <target name="gui">
-    <exec dir="${staf.install.dir}"
+    <exec dir="${staf.install.dir}/${staf.name}"
           executable="${java.path}/bin/java"
           spawn="true">
-      <env key="${var.path}" path="${java.path}${file.separator}bin${path.separator}${staf.install.dir}${file.separator}bin"/>
+      <env key="${var.path}" path="${java.path}$/bin:${staf.install.dir}/${staf.name}/bin"/>
       <env key="LD_LIBRARY_PATH" path="${staf.lib.dir}"/>
-      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar${path.separator}:."/>
-      <env key="STAFCONVDIR" value="${staf.install.dir}/codepage"/>
+      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar:."/>
+      <env key="STAFCONVDIR" value="${staf.install.dir}/${staf.name}/codepage"/>
       <arg value="-classpath"/>
-      <arg value="${staf.install.dir}/services/stax/STAXMon.jar${path.separator}${staf.lib.dir}/JSTAF.jar"/>
+      <arg value="${staf.install.dir}/${stax.name}/STAXMon.jar:${staf.lib.dir}/JSTAF.jar"/>
       <arg value="com.ibm.staf.service.stax.STAXMonitor"/>
     </exec>
   </target>
 
   <!-- Display jvmlogs -->
   <target name="jvmlogs">
-    <exec dir="${staf.install.dir}"
+    <exec dir="${staf.install.dir}/${staf.name}"
           executable="${java.path}/bin/java"
           spawn="true">
-      <env key="${var.path}" path="${java.path}${file.separator}bin${path.separator}${staf.install.dir}${file.separator}bin"/>
+      <env key="${var.path}" path="${java.path}/bin:${staf.install.dir}/${staf.name}/bin"/>
       <env key="LD_LIBRARY_PATH" path="${staf.lib.dir}"/>
-      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar${path.separator}:."/>
-      <env key="STAFCONVDIR" value="${staf.install.dir}/codepage"/>
+      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar:."/>
+      <env key="STAFCONVDIR" value="${staf.install.dir}/${staf.name}/codepage"/>
       <arg value="-classpath"/>
       <arg value="${staf.lib.dir}${path.separator}${staf.lib.dir}/JSTAF.jar"/>
       <arg value="com.ibm.staf.STAFJVMLogViewer"/>
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/ant/tests.xml b/opendj-sdk/opends/tests/staf-tests/shared/ant/tests.xml
index 163b40f..1976929 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/ant/tests.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/ant/tests.xml
@@ -95,17 +95,17 @@
     <property name="tests.request" value="EXECUTE FILE ${tests.xml} JOBNAME OpenDS_${tests.type} SCRIPTFILE ${tests.run.dir}/${tests.run.time}/config/${tests.config.file} WAIT CLEARLOGS"/>
 
     <echo>While the tests are running you may tail the job logs at</echo>
-    <echo>${staf.install.dir}/logs/MACHINE/${host.name}</echo>
+    <echo>${staf.install.dir}/${staf.name}/logs/MACHINE/${host.name}</echo>
     <echo>Running tests. This will take more than a while.</echo>
-    <property name="CLASSPATH" value="${staf.lib.dir}/JSTAF.jar${path.separator}${e.CLASSPATH}"/>
+    <property name="CLASSPATH" value="${staf.lib.dir}/JSTAF.jar:."/>
     <exec
       dir="${staf.bin.dir}"
       executable="${staf.executable}"
       >
       <arg line="LOCAL STAX ${tests.request}"/>
-      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar${path.separator}${e.CLASSPATH}"/>
+      <env key="CLASSPATH" path="${staf.lib.dir}/JSTAF.jar:."/>
       <env key="LD_LIBRARY_PATH" value="${staf.lib.dir}"/>
-      <env key="STAFCONVDIR" value="${staf.install.dir}/codepage"/>
+      <env key="STAFCONVDIR" value="${staf.install.dir}/${staf.name}/codepage"/>
       <env key="STAFCODEPAGE" value="LATIN_1"/>
     </exec>
 
@@ -165,6 +165,10 @@
                defaultvalue="${ldclt.dir}"
                addproperty="ldclt.dir.input"/>
       </then>
+      <else>
+        <property name="client.hostname.input" value="${client.hostname}"/>
+        <property name="ldclt.dir.input" value="${ldclt.dir}"/>
+      </else>
     </if>
 
     <input message="   Enter path to logs directory:"
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/MANIFEST.MF b/opendj-sdk/opends/tests/staf-tests/shared/dsml/MANIFEST.MF
new file mode 100644
index 0000000..76df4a2
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+
+Name: staf/service/info
+Service-Class: com.ibm.staf.service.opends.DSMLService
+Packaged-Jars: OpenDS
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/dsmlService.jar b/opendj-sdk/opends/tests/staf-tests/shared/dsml/dsmlService.jar
deleted file mode 100755
index b56e1fd..0000000
--- a/opendj-sdk/opends/tests/staf-tests/shared/dsml/dsmlService.jar
+++ /dev/null
Binary files differ
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/DSMLService.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/DSMLService.java
new file mode 100644
index 0000000..4d6d447
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/DSMLService.java
@@ -0,0 +1,485 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+package com.ibm.staf.service.opends;
+
+import com.ibm.staf.*;
+import com.ibm.staf.wrapper.*;
+import com.ibm.staf.service.*;
+import com.ibm.staf.service.opends.tester.*;
+import java.util.StringTokenizer;
+import java.io.*;
+import java.util.ArrayList;
+
+/**
+ * DSML Staf service 
+ * it allows :
+ *  - to test one or multiple DSEE DSML suite testcases (TODO)
+ *  - compare testcase result against expected result
+ */
+public class DSMLService implements STAFServiceInterfaceLevel30 {
+
+  private static final String OP_COMPARE = "COMPARE";
+  private static final String OP_HELP = "HELP";
+  private static final String OP_FILE = "FILE";
+  private static final String OP_EXP_FILE = "EXP_FILE";
+  private static final String OP_ISSUE_FILE = "ISSUE_FILE";
+  private static final String OP_DIR = "DIR";
+  private static final String OP_EXP_DIR = "EXP_DIR";
+  private final String MATCH = " matches ";
+  private final String DIFFER = " differs from ";
+  private String fServiceName;
+  private STAFHandle fHandle;
+  private String fLocalMachineName = "";
+  private STAFLog logger = null;
+
+  // Define any error codes unique to this service
+  private static final int kDSMLInvalidSomething = 4001;
+
+  // STAFCommandParsers for each request
+  private STAFCommandParser fCompareParser;
+  private String fLineSep;
+
+  public STAFResult init(STAFServiceInterfaceLevel30.InitInfo info) {
+    try {
+      fServiceName = info.name;
+      fHandle = new STAFHandle("STAF/Service/" + info.name);
+      logger = new STAFLog(STAFLog.HANDLE, "dsmlLog", fHandle,
+              STAFLog.Fatal | STAFLog.Error | STAFLog.Warning);
+    } catch (STAFException e) {
+      return new STAFResult(STAFResult.STAFRegistrationError,
+              e.toString());
+    }
+
+    // COMPARE parser
+    fCompareParser = new STAFCommandParser(0, false);
+    fCompareParser.addOption(OP_COMPARE, 1, STAFCommandParser.VALUENOTALLOWED);
+    fCompareParser.addOption(OP_FILE, 1, STAFCommandParser.VALUEREQUIRED);
+    //fCompareParser.addOption(OP_F_SHORTCUT, 0, STAFCommandParser.VALUEREQUIRED);
+    fCompareParser.addOption(OP_DIR, 1, STAFCommandParser.VALUEREQUIRED);
+    fCompareParser.addOption(OP_EXP_FILE, 1, STAFCommandParser.VALUEREQUIRED);
+    fCompareParser.addOption(OP_EXP_DIR, 1, STAFCommandParser.VALUEREQUIRED);
+    //fCompareParser.addOption(OP_DIR_SHORT, 0, STAFCommandParser.VALUEREQUIRED);
+    //fCompareParser.addOption(OP_D_SHORTCUT, 0, STAFCommandParser.VALUEREQUIRED);
+    // either we compare directory or file
+    //fCompareParser.addOptionGroup(OP_FILE_GROUP, 1, 3);
+    //fCompareParser.addOptionGroup(OP_DIR_GROUP, 1, 3);
+    //TODO.1 not needed per dependency below 
+    //TODO.1 fCompareParser.addOptionGroup(OP_EXPECTED_GROUP, 0, 1);
+    //TODO.1 fCompareParser.addOptionNeed(OP_EXPECTED_RESULT_FILE, OP_RESULT_FILE);
+    //TODO.1 fCompareParser.addOptionNeed(OP_EXPECTED_RESULT_DIR, OP_RESULT_DIR);
+
+    // if you specify COMPARE, RESULT_FILE is required
+    fCompareParser.addOptionNeed(OP_FILE, OP_EXP_FILE);
+    fCompareParser.addOptionNeed(OP_EXP_FILE, OP_FILE);
+    fCompareParser.addOptionNeed(OP_DIR, OP_EXP_DIR);
+    fCompareParser.addOptionNeed(OP_EXP_DIR, OP_DIR);
+    fCompareParser.addOptionNeed(OP_COMPARE, OP_FILE + " " + OP_DIR);
+    fCompareParser.addOptionNeed(OP_FILE + " " + OP_DIR, OP_COMPARE);
+
+    STAFResult res = new STAFResult();
+
+    // Resolve the line separator variable for the local machine
+    res = STAFUtil.resolveInitVar("{STAF/Config/Sep/Line}", fHandle);
+
+    if (res.rc != STAFResult.Ok) {
+      return res;
+    }
+
+    fLineSep = res.result;
+
+    // Resolve the machine name variable for the local machine
+    res = STAFUtil.resolveInitVar("{STAF/Config/Machine}", fHandle);
+
+    if (res.rc != STAFResult.Ok) {
+      return res;
+    }
+
+    fLocalMachineName = res.result;
+
+    // Register Help Data
+    registerHelpData(
+            kDSMLInvalidSomething+1,
+            "Invalid input",
+            "missing or wrong input files for results or expected results");
+
+    return new STAFResult(STAFResult.Ok);
+  }
+
+  public STAFResult acceptRequest(STAFServiceInterfaceLevel30.RequestInfo info) {
+    // dumping the RequestInfo
+    //TODO
+
+    //delegate the request handling
+    StringTokenizer requestTokenizer = new StringTokenizer(info.request);
+    String request = requestTokenizer.nextToken().toLowerCase();
+
+    // call the appropriate method to handle the command
+    if (request.equalsIgnoreCase(OP_COMPARE)) {
+      return handleCompare(info);
+    } else if (request.equalsIgnoreCase(OP_HELP)) {
+      return handleHelp(info);
+    } else {
+      return handleInvalidRequest(info);
+    }
+  }
+
+  public STAFResult term() {
+    logger.log(STAFLog.Warning, "termination initiated");
+    try {
+      // Un-register Help Data
+
+      unregisterHelpData(kDSMLInvalidSomething+2);
+
+      // Un-register the service handle
+
+      fHandle.unRegister();
+    } catch (STAFException ex) {
+      return new STAFResult(STAFResult.STAFRegistrationError,
+              ex.toString());
+    }
+
+    return new STAFResult(STAFResult.Ok);
+  }
+
+  private STAFResult handleCompare(STAFServiceInterfaceLevel30.RequestInfo info) {
+    STAFResult sr = new STAFResult(0);
+
+    //parse the input request 
+    STAFCommandParseResult parsedRequest = fCompareParser.parse(info.request);
+    if (parsedRequest.rc != STAFResult.Ok) {
+      return new STAFResult(STAFResult.InvalidRequestString,
+              parsedRequest.errorBuffer);
+    }
+
+    // Resolve any STAF variables in the DIR option's value
+    STAFResult res = new STAFResult();
+
+    String file = parsedRequest.optionValue(OP_FILE);
+    String exp_file = parsedRequest.optionValue(OP_EXP_FILE);
+    String dir = parsedRequest.optionValue(OP_DIR);
+    String exp_dir = parsedRequest.optionValue(OP_EXP_DIR);
+
+    if (dir != null && dir.trim().length() > 0) {
+      sr = handleCompareDir(exp_dir, dir);
+    }
+
+    if (file != null && file.trim().length() > 0) {
+      sr = handleCompareFile(exp_file, file);
+    }
+
+
+    return sr;
+  }
+
+  /*
+   * It's expected that the result and expected result file have the same
+   * file path up to the file extension.
+   * expected result having extension ".res"
+   * result to be compared to expected result ".run"
+   * The filePath should exclude the file extension
+   * for ex a file like /tmp/add000.res the filePath expected is /tmp/add000
+   */
+  private STAFResult handleCompareFile(String exp_file, String file) {
+    STAFResult sr = new STAFResult(STAFResult.Ok);
+    logger.log(STAFLog.Warning,
+            "handle File compare for exp_file=[" + exp_file + "], file=[" + file + "]");
+    if (!(exp_file.endsWith(DSMLFileFilter.EXPECTED_FILE_EXTENSION) || exp_file.endsWith(DSMLFileFilter.ISSUE_FILE_EXTENSION))){
+      sr.rc = STAFResult.FileReadError;
+      sr.result = "invalid input " + exp_file + " should end with " + 
+              DSMLFileFilter.EXPECTED_FILE_EXTENSION + " or " +
+              DSMLFileFilter.ISSUE_FILE_EXTENSION;
+    } else if (!file.endsWith(DSMLFileFilter.RUN_FILE_EXTENSION)) {
+      sr.rc = STAFResult.FileReadError;
+      sr.result = "invalid input " + file + " should end with " + DSMLFileFilter.RUN_FILE_EXTENSION;
+    } else {
+      File expectedFile, resultFile;
+      // read the result and expected content files, and compare theme
+      try {
+        expectedFile = new File(exp_file);
+        resultFile = new File(file);
+        String line;
+        //reading result into ArrayList of POST results
+        BufferedReader resultBuffReader = new BufferedReader(new FileReader(resultFile));
+        ArrayList rl = new ArrayList();
+        StringBuffer resultContent = new StringBuffer();
+        int ln = 0;
+        while ((line = resultBuffReader.readLine()) != null) {
+          if (line.startsWith("HTTP") && ln > 0) {
+            rl.add(resultContent);
+            resultContent = new StringBuffer(line + "\n");
+          } else {
+            resultContent.append(line + "\n");
+          }
+          ln++;
+        }
+        rl.add(resultContent.toString());
+        resultBuffReader.close();
+        //reading expected result of POST results
+        BufferedReader expectedBufferReader = new BufferedReader(new FileReader(expectedFile));
+        ArrayList erl = new ArrayList();
+        StringBuffer expectedContent = new StringBuffer();
+        ln = 0;
+        while ((line = expectedBufferReader.readLine()) != null) {
+          if (line.startsWith("HTTP") && ln > 0) {
+            erl.add(expectedContent);
+            expectedContent = new StringBuffer(line + "\n");
+          } else {
+            expectedContent.append(line + "\n");
+          }
+          ln++;
+        }
+        erl.add(expectedContent.toString());
+        expectedBufferReader.close();
+        if (rl.size() != erl.size()) {
+          sr.rc = kDSMLInvalidSomething+3;//TODO
+          sr.result = "number of results " +
+                  resultFile + "[" + rl.size() + "]" +
+                  expectedFile + "[" + erl.size() + "]";
+        } else {
+          boolean identical = true;
+          for (int i = 0; i < rl.size(); i++) {
+            //starting from 1, because the first is always empty
+            /*PIERRE choose this one or below
+             identical &= compareResults("HTTP" + erl.get(i),
+                    "HTTP" + rl.get(i));
+             * */
+             identical &= compareResults((String) erl.get(i), (String) rl.get(i));
+             logger.log(STAFLog.Warning, "comparing\n"+(String)erl.get(i)+"\nwith\n"+ (String)rl.get(i));
+            if (identical) {
+              // success
+              sr.rc = STAFResult.Ok;
+              sr.result = resultFile + MATCH + expectedFile;
+            } else {
+              logger.log(STAFLog.Error, "exp_file=[" + exp_file + "] "+
+                                        "differ from file=[" + file + "]");
+
+              sr.rc = kDSMLInvalidSomething+4;
+              sr.result = resultFile + DIFFER + expectedFile;
+              break;
+            }
+          }
+        }
+      } catch (FileNotFoundException fnfe) {
+        sr.rc = kDSMLInvalidSomething+5;//TODO
+        sr.result = fnfe.getMessage();
+      } catch (IOException ioe) {
+        sr.rc = kDSMLInvalidSomething+6;//TODO
+        sr.result = ioe.getMessage();
+      } catch (Exception e) {
+        sr.rc = kDSMLInvalidSomething+7;//TODO
+        sr.result = e.getMessage();
+      }
+    }
+    return sr;
+  }
+
+  private STAFResult handleCompareDir(String exp_dir, String run_dir) {
+    logger.log(STAFLog.Warning,
+            "handle Directory comparaison exp_dir[" + exp_dir + "],dir[" + run_dir + "]");
+    File expDirFile;
+    File runDirFile;
+    STAFResult sr = new STAFResult(STAFResult.Ok);
+    try {
+      expDirFile = new File(exp_dir);
+      runDirFile = new File(run_dir);
+      ArrayList test_a = new ArrayList();
+      ArrayList missing_e = new ArrayList();
+      ArrayList missing_r = new ArrayList();
+      if (expDirFile.isDirectory() && runDirFile.isDirectory()) {
+        // find all the files with extension ".res"
+        File[] eFiles = expDirFile.listFiles(new DSMLFileFilter(DSMLFileFilter.EXPECTED_FILE_EXTENSION));
+        ArrayList ea = new ArrayList(eFiles.length);
+        String eName;
+        for (int ei = 0; ei < eFiles.length; ei++) {
+          eName = eFiles[ei].getName();
+          eName = eName.substring(0,eName.lastIndexOf(DSMLFileFilter.EXPECTED_FILE_EXTENSION));
+          ea.add(eName);
+        }
+        // find all the files with extension ".run"
+        File[] rFiles = runDirFile.listFiles(new DSMLFileFilter(DSMLFileFilter.RUN_FILE_EXTENSION));
+        ArrayList ra = new ArrayList(rFiles.length);
+        String rName;
+        for (int ri = 0; ri < rFiles.length; ri++) {
+          rName = rFiles[ri].getName();
+          rName = rName.substring(0,rName.lastIndexOf(DSMLFileFilter.RUN_FILE_EXTENSION));
+          ra.add(rName);
+          if (!ea.contains(rName)) {
+            // get a run file not matching expected result
+            missing_e.add(rName);
+          } else {
+            // expected and run file are both present
+            test_a.add(rName);
+          }
+        }
+        // find the missing result file and remove from test_a
+        for (int i=0; i< ea.size(); i++) {
+          String e = (String) ea.get(i);
+          if (!ra.contains(e)) {
+            missing_r.add(e);
+          }
+        }
+        // loop through the test set test_a and compare the files
+        for (int i=0 ; i < test_a.size(); i++) {
+          String tf = (String) test_a.get(i);
+          sr = handleCompareFile(
+                  exp_dir+File.separator+tf+DSMLFileFilter.EXPECTED_FILE_EXTENSION,
+                  run_dir+File.separator+tf+DSMLFileFilter.RUN_FILE_EXTENSION);
+        }
+      } else {
+        logger.log(STAFLog.Warning, "Directory comparaison with invalid input dir : " + exp_dir);
+        sr.rc = kDSMLInvalidSomething+8;
+        sr.result = "Directory comparaison with invalid input dir : " + exp_dir;
+      }
+    } catch (Exception e) {
+      sr.rc = kDSMLInvalidSomething+9;
+      sr.result = e.getMessage();
+    }
+    return sr;
+  }
+
+  private boolean compareResults(String expectedResult, String result) throws Exception {
+
+    ResponseChecker dsmlReponse = null;
+    ResponseChecker expectedReponse = null;
+
+    //System.out.println("result\n" + result);
+    try {
+      dsmlReponse = new ResponseChecker(result);
+    } catch (Exception e) {
+      if (e.getCause() != null) {
+        e.printStackTrace();
+        throw (new Exception("Response parsing error: " + e.getCause().getMessage()));
+      } else {
+        e.printStackTrace();
+        throw (new Exception("Response parsing error: " + e.getMessage()));
+      }
+    }
+
+
+    try {
+      expectedReponse = new ResponseChecker(expectedResult);
+    } catch (Exception e) {
+      if (e.getCause() != null) {
+        throw (new Exception("Parsing error for expected result : " + e.getCause().getMessage()));
+      } else {
+        throw (new Exception("Parsing error for expected result : " + e.getMessage()));
+      }
+    }
+
+    try {
+      return (dsmlReponse.equals(expectedReponse));
+    } catch (Exception e) {
+      logger.log(STAFLog.Warning, "failed comparing DSML responses exception " + e.getMessage());
+      return false;
+    }
+  }
+
+  private STAFResult handleInvalidRequest(STAFServiceInterfaceLevel30.RequestInfo info) {
+    logger.log(STAFLog.Error, "invalid request : [" + info.request + "]");
+    STAFResult sr = new STAFResult(kDSMLInvalidSomething+10);
+    sr.result = info.request;
+    return sr;
+  }
+
+  private STAFResult handleHelp(STAFServiceInterfaceLevel30.RequestInfo info) {
+    // Verify the requester has at least trust level 1
+
+    STAFResult trustResult = STAFUtil.validateTrust(
+            1, fServiceName, "HELP", fLocalMachineName, info);
+
+    if (trustResult.rc != STAFResult.Ok) {
+      return trustResult;
+    }
+
+    // Return help text for the service
+
+    return new STAFResult(
+            STAFResult.Ok,
+            "DSML Service Help :" + fLineSep + fLineSep + OP_COMPARE + "(" +
+            OP_EXP_FILE + " filename " + OP_FILE + " filename " + " | " +
+            OP_EXP_DIR + " dirname " + OP_DIR + " dirname )" +
+            fLineSep + OP_HELP);
+  }
+
+
+  // Register error codes for the STAX Service with the HELP service
+  private void registerHelpData(int errorNumber, String info,
+          String description) {
+  //TODO
+  }
+
+  // Un-register error codes for the STAX Service with the HELP service
+  private void unregisterHelpData(int errorNumber) {
+  //TODO
+  }
+
+  private class DSMLFileFilter implements FilenameFilter {
+
+    public static final String EXPECTED_FILE_EXTENSION = ".res";
+    public static final String ISSUE_FILE_EXTENSION = ".issue";
+    public static final String RUN_FILE_EXTENSION = ".run";
+    public static final String INPUT_FILE_EXTENSION = ".dat";
+    private ArrayList extList;
+    private String exclusiveExtension;
+
+    DSMLFileFilter() {
+      extList = new ArrayList();
+      exclusiveExtension = null;
+      extList.add(EXPECTED_FILE_EXTENSION);
+      extList.add(ISSUE_FILE_EXTENSION);
+      extList.add(RUN_FILE_EXTENSION);
+      extList.add(INPUT_FILE_EXTENSION);
+    }
+
+    DSMLFileFilter(String ext) {
+      exclusiveExtension = ext;
+    }
+
+    public boolean accept(File dir, String name) {
+      int li = name.lastIndexOf(".");
+      if (li > 0) {
+        if (exclusiveExtension != null) {
+          //comparing file name extension with exclusively one extension
+          if (name.substring(li).equals(exclusiveExtension)) {
+            return ((new File(dir + File.separator + name)).isFile());
+          } else {
+            return false;
+          }
+        } else {
+          // compare file name extension 
+          if (extList.contains(name.substring(li))) {
+            return ((new File(dir + File.separator + name)).isFile());
+          } else {
+            return false;
+          }
+        }
+      } else {
+        return false;
+      }
+    }
+  }
+}
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/Checker.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/Checker.java
new file mode 100644
index 0000000..76125e0
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/Checker.java
@@ -0,0 +1,235 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/proctor/resource/legal-notices/Proctor.LICENSE
+ * or https://proctor.dev.java.net/Proctor.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package com.ibm.staf.service.opends.tester;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import javax.xml.bind.JAXBElement;
+import java.util.Collection;
+import java.util.Collections;
+import org.opends.dsml.protocol.DsmlAttr;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+
+public class Checker {
+
+    private static final String JAXB_GENERATED_PACKAGE_NAME = "org.opends.dsml.protocol";
+
+    // Key=JAXB classes, Value=List of methods to get attribute
+    private static final Map<Class, List<Method>> CACHE = new HashMap<Class, List<Method>>();
+
+    // Helpfull to keep track of what argument is currently processed
+    private static final Stack<Method> STACK = new Stack<Method>();
+
+    // A list of attribute that are prevented to be checked
+    private static final Set<String> DO_NOT_CHECK = new HashSet<String>();
+
+    static {
+        DO_NOT_CHECK.add("ResultCode.getDescr"); // ResultCode.getCode is enough
+        DO_NOT_CHECK.add("LDAPResult.getErrorMessage"); // LDAPResult.getResultCode is enough
+        DO_NOT_CHECK.add("ErrorResponse.getMessage");
+    }
+    private static DsmlAttrCompare dsmlAttrCompare = new DsmlAttrCompare();
+
+    static {
+      // needed otherwise the SearchResultEntry like in test moddn998.res fail
+      // in the equals() method on DN.decode((String) o1....
+      DirectoryServer.bootstrapClient();
+    }
+
+    private static List<Method> getAttributes(Class clazz) {
+        List<Method> result = CACHE.get(clazz);
+        if (result == null) {
+            result = new ArrayList<Method>();
+
+            for (Method method : clazz.getMethods()) {
+                String methodName = method.getName();
+                Class returnType = method.getReturnType();
+                if (!method.getDeclaringClass().getName().startsWith(JAXB_GENERATED_PACKAGE_NAME)) {
+                    continue;
+                }
+                if (((methodName.startsWith("get") && (methodName.length() > 3) && (!returnType.equals(void.class))) || (methodName.startsWith("is") && (methodName.length() > 2) && (returnType.equals(boolean.class)))) && (method.getParameterTypes().length == 0)) {
+                    result.add(method);
+                }
+            }
+            CACHE.put(clazz, result);
+        }
+        return result;
+    }
+
+    private static String buildMessage() {
+
+        // return "";
+
+        StringBuilder sb = new StringBuilder(STACK.peek().toGenericString()).append(" in JAXB ");
+        int size = STACK.size();
+        for (int i = 0; i < size; i++) {
+            sb.append(i == 0 ? "" : ".").append(STACK.get(i).getName()).append("()");
+        }
+        return sb.toString();
+
+    }
+
+    public static boolean equals(Object o1, Object o2) {
+        if (o1 == null && o2 == null) {
+            return true;
+        }
+        if (o1 == null  || o2 == null) {
+            throw new JAXBCheckerException("One of the two is null : " + buildMessage());
+        }
+        // both are not null
+        Class c1 = o1.getClass();
+        if (!o2.getClass().equals(c1)) {
+            throw new JAXBCheckerException("Type mismatch (" + c1.getName() + " vs " + o2.getClass().getName() + ") : " + buildMessage());
+        }
+
+        if (c1.getName().startsWith(JAXB_GENERATED_PACKAGE_NAME)) {
+            for (Method method : getAttributes(c1)) {
+                String fullName = method.getDeclaringClass().getName() + "." + method.getName();
+                String s = fullName.substring(JAXB_GENERATED_PACKAGE_NAME.length() + 1, fullName.length());
+                if (DO_NOT_CHECK.contains(s)) {
+                    continue;
+                }
+                Object r1, r2;
+                try {
+                    STACK.push(method);
+                    r1 = method.invoke(o1);
+                    r2 = method.invoke(o2);
+                    if (!equals(r1, r2)) {
+                        // if false an exception will be thown
+                        STACK.pop();
+                        return false;
+                    }
+                    STACK.pop();
+                } catch (Exception e) {
+                    throw (RuntimeException) e;
+                }
+            }
+        } else if (o1 instanceof List) {
+            // Transering into sets whenever ordering is required
+            Collection l1;
+            Collection l2;
+
+            l1 = (List) o1;
+            l2 = (List) o2;
+
+            if (l1 != null &&
+              l1.size() > 1 &&
+              l1.toArray()[0] instanceof DsmlAttr) {
+                Collections.sort((List) l1, dsmlAttrCompare);
+                Collections.sort((List) l2, dsmlAttrCompare);
+            } else if (l1 != null &&
+              l1.size() > 1 &&
+              l1.toArray()[0] instanceof String) {
+                Collections.sort((List) l1);
+                Collections.sort((List) l2);
+            }
+
+            /*
+            if (((List) o2).size() != l2.size()) {
+                for (Object o : l2) {
+                    System.out.println("collection2 : " + o);
+                }
+                for (Object o : (List) o2) {
+                    System.out.println("list2 : " + o);
+                }
+                throw (new RuntimeException("object2 size changed"));
+            }
+*/
+            if (l1.size() != l2.size()) {
+
+                for (Object o : l1) {
+                    System.out.println("list1 : " + o);
+                }
+                for (Object o : l2) {
+                    System.out.println("list2 : " + o);
+                }
+                throw new JAXBCheckerException("List size mismatch (received=" + l1.size() + ", expected=" + l2.size() + "): " + buildMessage());
+            }
+
+            for (int i = 0; i < l1.size(); i++) {
+                // could be optimized :(
+                if (!equals(l1.toArray()[i], l2.toArray()[i])) {
+                    // if false an exception will be thown
+                    return false;
+                }
+            }
+        } else if (o1 instanceof JAXBElement) {
+            return equals(((JAXBElement) o1).getValue(), ((JAXBElement) o2).getValue());
+        } else if (o1 instanceof String) {
+            // special case in case a DN must be checked
+            // This is not a full check for DN but DN.decode(String) needs a DS to run
+            if (STACK.size() > 0) {
+                String s = STACK.peek().getName();
+                if (s.equalsIgnoreCase("getDn") ||
+                  s.equalsIgnoreCase("getMatchedDN")) {
+                    try {
+                        if (!DN.decode((String) o1).equals(DN.decode((String) o2))) {
+                            throw new JAXBCheckerException("DN mismatch : " + o1 + "  vs " + o2 + " " + buildMessage());
+                        }
+                    } catch (DirectoryException ex) {
+                        throw new JAXBCheckerException("DN mismatch : " + o1 + "  vs " + o2 + " " + buildMessage());
+                    }
+//                    String oo1 = ((String) o1).replace(" ", "");
+//                    String oo2 = ((String) o2).replace(" ", "");
+//                    if (!oo1.equalsIgnoreCase(oo2)) {
+//                        throw new JAXBCheckerException("DN mismatch : " + o1 + "  vs " + o2 + " " + buildMessage());
+//                    }
+                } else if (s.equalsIgnoreCase("getName")) {
+                    if (!((String) o1).equalsIgnoreCase((String) o2)) {
+                        throw new JAXBCheckerException("Attribute mismatch : " + o1 + "  vs " + o2 + " " + buildMessage());
+                    }
+                } else {
+                    if (!o1.equals(o2)) {
+                        throw new JAXBCheckerException("String mismatch : " + o1 + "  vs " + o2 + " " + buildMessage());
+                    }
+                }
+            }
+        } else {
+            if (!o1.equals(o2)) {
+                if (STACK.size() > 0) {
+                    String s = STACK.peek().getName();
+                    if (s.equalsIgnoreCase("getCode")) {
+                        throw new JAXBCheckerException("Error code mismatch : " + LDAPResultCode.toString((Integer) o1) + "[" + o1 + "] vs " + LDAPResultCode.toString((Integer) o2) + "[" + o2 + "]" + buildMessage());
+                    } else {
+                        throw new JAXBCheckerException("Object mismatch : [class = " + o1.getClass().getSimpleName() + "]" + buildMessage());
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+} 
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/DsmlAttrCompare.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/DsmlAttrCompare.java
new file mode 100644
index 0000000..89026ea
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/DsmlAttrCompare.java
@@ -0,0 +1,40 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/proctor/resource/legal-notices/Proctor.LICENSE
+ * or https://proctor.dev.java.net/Proctor.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package com.ibm.staf.service.opends.tester;
+
+import java.util.Comparator;
+import org.opends.dsml.protocol.DsmlAttr;
+
+public class DsmlAttrCompare implements Comparator {
+
+    public int compare(Object o1, Object o2) {
+        DsmlAttr attr1 = (DsmlAttr) o1;
+        DsmlAttr attr2 = (DsmlAttr) o2;
+        return (attr1.getName().compareTo(attr2.getName()));
+    }
+}
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/JAXBCheckerException.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/JAXBCheckerException.java
new file mode 100644
index 0000000..d0aaf33
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/JAXBCheckerException.java
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/proctor/resource/legal-notices/Proctor.LICENSE
+ * or https://proctor.dev.java.net/Proctor.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package com.ibm.staf.service.opends.tester;
+
+public class JAXBCheckerException extends RuntimeException {
+
+    public JAXBCheckerException(String message) {
+        super(message);
+    }
+    
+}
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/LDAPResultCode.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/LDAPResultCode.java
new file mode 100644
index 0000000..b8c38fd
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/LDAPResultCode.java
@@ -0,0 +1,810 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package com.ibm.staf.service.opends.tester;
+
+/**
+ * This class defines a set of constants that correspond to the result codes
+ * defined in the LDAP protocol.  Note that many (but not all) of the result
+ * codes numbered 81 and higher come from the LDAP C API specification and are
+ * only intended for client-side use and should not be returned from the
+ * Directory Server.  These are denoted with a "CLIENT_SIDE_" prefix.
+ */
+public class LDAPResultCode
+{
+  /**
+   * The LDAP result code for successful operations.
+   */
+  public static final int SUCCESS = 0;
+
+
+
+  /**
+   * The LDAP result code for operations that fail due to an operations error.
+   */
+  public static final int OPERATIONS_ERROR = 1;
+
+
+
+  /**
+   * The LDAP result code for operations that fail due to a protocol error.
+   */
+  public static final int PROTOCOL_ERROR = 2;
+
+
+
+  /**
+   * The LDAP result code for operations that fail as a result of exceeding a
+   * time limit.
+   */
+  public static final int TIME_LIMIT_EXCEEDED = 3;
+
+
+
+  /**
+   * The LDAP result code for operations that fail as a result of exceeding a
+   * size limit.
+   */
+  public static final int SIZE_LIMIT_EXCEEDED = 4;
+
+
+
+  /**
+   * The LDAP result code for compare operations in which the assertion is
+   * false.
+   */
+  public static final int COMPARE_FALSE = 5;
+
+
+
+  /**
+   * The LDAP result code for compare operations in which the assertion is true.
+   */
+  public static final int COMPARE_TRUE = 6;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * authentication method is not supported.
+   */
+  public static final int AUTH_METHOD_NOT_SUPPORTED = 7;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because strong authentication
+   * is required.
+   */
+  public static final int STRONG_AUTH_REQUIRED = 8;
+
+
+
+  /**
+   * The LDAP result code for operations that encountered a referral.
+   */
+  public static final int REFERRAL = 10;
+
+
+
+  /**
+   * The LDAP result code for operations that fail as a result of exceeding an
+   * administrative limit.
+   */
+  public static final int ADMIN_LIMIT_EXCEEDED = 11;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because they contain an
+   * unavailable critical extension.
+   */
+  public static final int UNAVAILABLE_CRITICAL_EXTENSION = 12;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because confidentiality is
+   * required.
+   */
+  public static final int CONFIDENTIALITY_REQUIRED = 13;
+
+
+
+  /**
+   * The LDAP result code used for multi-stage SASL bind operations that are not
+   * yet complete.
+   */
+  public static final int SASL_BIND_IN_PROGRESS = 14;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a specified attribute
+   * does not exist.
+   */
+  public static final int NO_SUCH_ATTRIBUTE = 16;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a specified attribute
+   * type is not defined in the server schema.
+   */
+  public static final int UNDEFINED_ATTRIBUTE_TYPE = 17;
+
+
+
+  /**
+   * The LDAP result code for operations that fail as a result of attempting an
+   * inappropriate form of matching on an attribute.
+   */
+  public static final int INAPPROPRIATE_MATCHING = 18;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a defined constraint
+   * has been violated.
+   */
+  public static final int CONSTRAINT_VIOLATION = 19;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because of a conflict with an
+   * existing attribute or value.
+   */
+  public static final int ATTRIBUTE_OR_VALUE_EXISTS = 20;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because of an invalid
+   * attribute syntax.
+   */
+  public static final int INVALID_ATTRIBUTE_SYNTAX = 21;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a targeted entry does
+   * not exist.
+   */
+  public static final int NO_SUCH_OBJECT = 32;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the an alias was
+   * encountered in an illegal context.
+   */
+  public static final int ALIAS_PROBLEM = 33;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the request included
+   * a malformed DN.
+   */
+  public static final int INVALID_DN_SYNTAX = 34;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a problem occurred
+   * while attempting to dereference an alias.
+   */
+  public static final int ALIAS_DEREFERENCING_PROBLEM = 36;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the user attempted to
+   * perform a type of authentication that was inappropriate for the targeted
+   * entry.
+   */
+  public static final int INAPPROPRIATE_AUTHENTICATION = 48;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the user supplied
+   * invalid credentials for an authentication attempt.
+   */
+  public static final int INVALID_CREDENTIALS = 49;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the client does not
+   * have permission to perform the requested operation.
+   */
+  public static final int INSUFFICIENT_ACCESS_RIGHTS = 50;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the server was too
+   * busy to process it.
+   */
+  public static final int BUSY = 51;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the server or a
+   * required resource was unavailable.
+   */
+  public static final int UNAVAILABLE = 52;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the server was
+   * unwilling to perform the requested operation.
+   */
+  public static final int UNWILLING_TO_PERFORM = 53;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because a referral or
+   * chaining loop was detected.
+   */
+  public static final int LOOP_DETECT = 54;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the request included
+   * a VLV request control without a server-side sort control.
+   */
+  public static final int SORT_CONTROL_MISSING = 60;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the request included
+   * a VLV request control with an invalid offset.
+   */
+  public static final int OFFSET_RANGE_ERROR = 61;
+
+
+
+  /**
+   * The LDAP result code for operations that fail due to a naming violation.
+   */
+  public static final int NAMING_VIOLATION = 64;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation would have resulted in an entry that violates the server schema.
+   */
+  public static final int OBJECTCLASS_VIOLATION = 65;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation is not allowed on non-leaf entries.
+   */
+  public static final int NOT_ALLOWED_ON_NONLEAF = 66;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation is not allowed on an RDN attribute.
+   */
+  public static final int NOT_ALLOWED_ON_RDN = 67;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation would have resulted in an entry that conflicts with one that
+   * already exists.
+   */
+  public static final int ENTRY_ALREADY_EXISTS = 68;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation attempted to modify objectclass values in an illegal manner.
+   */
+  public static final int OBJECTCLASS_MODS_PROHIBITED = 69;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the requested
+   * operation would have required interaction with multiple DSAs.
+   */
+  public static final int AFFECTS_MULTIPLE_DSAS = 71;
+
+
+
+  /**
+   * The LDAP result code for operations that fail due to an error in
+   * virtual list view processing.
+   */
+  public static final int VIRTUAL_LIST_VIEW_ERROR = 76;
+
+
+
+  /**
+   * The LDAP result code for use in cases in which none of the other defined
+   * result codes are appropriate.
+   */
+  public static final int OTHER = 80;
+
+
+
+  /**
+   * The client-side result code that indicates that a previously-established
+   * connection to the server was lost.  This is for client-side use only and
+   * should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_SERVER_DOWN = 81;
+
+
+
+  /**
+   * The client-side result code that indicates that a local error occurred that
+   * had nothing to do with interaction with the server.  This is for
+   * client-side use only and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_LOCAL_ERROR = 82;
+
+
+
+  /**
+   * The client-side result code that indicates that an error occurred while
+   * encoding a request to send to the server.  This is for client-side use only
+   * and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_ENCODING_ERROR = 83;
+
+
+
+  /**
+   * The client-side result code that indicates that an error occurred while
+   * decoding a response from the server.  This is for client-side use only and
+   * should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_DECODING_ERROR = 84;
+
+
+
+  /**
+   * The client-side result code that indicates that the client did not receive
+   * an expected response in a timely manner.  This is for client-side use only
+   * and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_TIMEOUT = 85;
+
+
+
+  /**
+   * The client-side result code that indicates that the user requested an
+   * unknown or unsupported authentication mechanism.  This is for client-side
+   * use only and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_AUTH_UNKNOWN = 86;
+
+
+
+  /**
+   * The client-side result code that indicates that the filter provided by the
+   * user was malformed and could not be parsed.  This is for client-side use
+   * only and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_FILTER_ERROR = 87;
+
+
+
+  /**
+   * The client-side result code that indicates that the user cancelled an
+   * operation.  This is for client-side use only and should never be
+   * transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_USER_CANCELLED = 88;
+
+
+
+  /**
+   * The client-side result code that indicates that there was a problem with
+   * one or more of the parameters provided by the user.  This is for
+   * client-side use only and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_PARAM_ERROR = 89;
+
+
+
+  /**
+   * The client-side result code that indicates that the client application was
+   * not able to allocate enough memory for the requested operation.  This is
+   * for client-side use only and should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_NO_MEMORY = 90;
+
+
+
+  /**
+   * The client-side result code that indicates that the client was not able to
+   * establish a connection to the server.  This is for client-side use only and
+   * should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_CONNECT_ERROR = 91;
+
+
+
+  /**
+   * The client-side result code that indicates that the user requested an
+   * operation that is not supported.  This is for client-side use only and
+   * should never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_NOT_SUPPORTED = 92;
+
+
+
+  /**
+   * The client-side result code that indicates that the client expected a
+   * control to be present in the response from the server but it was not
+   * included.  This is for client-side use only and should never be transferred
+   * over protocol.
+   */
+  public static final int CLIENT_SIDE_CONTROL_NOT_FOUND = 93;
+
+
+
+  /**
+   * The client-side result code that indicates that the server did not return
+   * any results for a search operation that was expected to match at least one
+   * entry.  This is for client-side use only and should never be transferred
+   * over protocol.
+   */
+  public static final int CLIENT_SIDE_NO_RESULTS_RETURNED = 94;
+
+
+
+  /**
+   * The client-side result code that indicates that the server has returned
+   * more matching entries for a search operation than have been processed so
+   * far.  This is for client-side use only and should never be transferred over
+   * protocol.
+   */
+  public static final int CLIENT_SIDE_MORE_RESULTS_TO_RETURN = 95;
+
+
+
+  /**
+   * The client-side result code that indicates that the client detected a
+   * referral loop caused by servers referencing each other in a circular
+   * manner.  This is for client-side use only and should never be transferred
+   * over protocol.
+   */
+  public static final int CLIENT_SIDE_CLIENT_LOOP = 96;
+
+
+
+  /**
+   * The client-side result code that indicates that the client reached the
+   * maximum number of hops allowed when attempting to follow a referral (i.e.,
+   * following one referral resulted in another referral which resulted in
+   * another referral and so on).  This is for client-side use only and should
+   * never be transferred over protocol.
+   */
+  public static final int CLIENT_SIDE_REFERRAL_LIMIT_EXCEEDED = 97;
+
+
+
+  /**
+   * The LDAP result code for cancel operations that are successful, or for
+   * operations that are canceled.
+   */
+  public static final int CANCELED = 118;
+
+
+
+  /**
+   * The LDAP result code for cancel operations that fail because the specified
+   * operation could not be found.
+   */
+  public static final int NO_SUCH_OPERATION = 119;
+
+
+
+  /**
+   * The LDAP result code for cancel operations that fail because the specified
+   * operation has already progressed too far to be canceled.
+   */
+  public static final int TOO_LATE = 120;
+
+
+
+  /**
+   * The LDAP result code for cancel operations that fail because the specified
+   * operation cannot be canceled.
+   */
+  public static final int CANNOT_CANCEL = 121;
+
+
+
+  /**
+   * The LDAP result code for operations that are rejected because the
+   * filter in the LDAP assertion control did not match the target entry.
+   */
+  public static final int ASSERTION_FAILED = 122;
+
+
+
+  /**
+   * The LDAP result code for operations that fail because the server refused
+   * the client's requested authorization.
+   */
+  public static final int AUTHORIZATION_DENIED = 123;
+
+
+
+  /**
+   * The LDAP result code for operations in which no action is taken because the
+   * request include the LDAP no-op control.
+   *
+   * FIXME -- This is a temporary result code for use until
+   *          draft-zeilenga-ldap-noop is updated and an official result code is
+   *          allocated for it.  In the meantime, this result appears to be the
+   *          one used by OpenLDAP as per the message at
+   *          http://www.openldap.org/lists/openldap-devel/200601/msg00143.html
+   *          (0x410e = 16654).
+   */
+  public static final int NO_OPERATION = 16654;
+
+
+
+  /**
+   * Retrieves a string representation of the provided LDAP result code.
+   *
+   * @param  resultCode  The LDAP result code value for which to obtain the
+   *                     string representation.
+   *
+   * @return  The string representation of the provided LDAP result code.
+   */
+  public static String toString(int resultCode)
+  {
+    String message;
+
+    switch (resultCode)
+    {
+      case SUCCESS:
+        message = "SUCCESS";
+        break;
+      case OPERATIONS_ERROR:
+        message = "OPERATIONS_ERROR";
+        break;
+      case PROTOCOL_ERROR:
+        message = "PROTOCOL_ERROR";
+        break;
+      case TIME_LIMIT_EXCEEDED:
+        message = "TIME_LIMIT_EXCEEDED";
+        break;
+      case SIZE_LIMIT_EXCEEDED:
+        message = "SIZE_LIMIT_EXCEEDED";
+        break;
+      case COMPARE_FALSE:
+        message = "COMPARE_FALSE";
+        break;
+      case COMPARE_TRUE:
+        message = "COMPARE_TRUE";
+        break;
+      case AUTH_METHOD_NOT_SUPPORTED:
+        message = "AUTH_METHOD_NOT_SUPPORTED";
+        break;
+      case STRONG_AUTH_REQUIRED:
+        message = "STRONG_AUTH_REQUIRED";
+        break;
+      case REFERRAL:
+        message = "REFERRAL";
+        break;
+      case ADMIN_LIMIT_EXCEEDED:
+        message = "ADMIN_LIMIT_EXCEEDED";
+        break;
+      case UNAVAILABLE_CRITICAL_EXTENSION:
+        message = "UNAVAILABLE_CRITICAL_EXTENSION";
+        break;
+      case CONFIDENTIALITY_REQUIRED:
+        message = "CONFIDENTIALITY_REQUIRED";
+        break;
+      case SASL_BIND_IN_PROGRESS:
+        message = "SASL_BIND_IN_PROGRESS";
+        break;
+      case NO_SUCH_ATTRIBUTE:
+        message = "NO_SUCH_ATTRIBUTE";
+        break;
+      case UNDEFINED_ATTRIBUTE_TYPE:
+        message = "UNDEFINED_ATTRIBUTE_TYPE";
+        break;
+      case INAPPROPRIATE_MATCHING:
+        message = "INAPPROPRIATE_MATCHING";
+        break;
+      case CONSTRAINT_VIOLATION:
+        message = "CONSTRAINT_VIOLATION";
+        break;
+      case ATTRIBUTE_OR_VALUE_EXISTS:
+        message = "ATTRIBUTE_OR_VALUE_EXISTS";
+        break;
+      case INVALID_ATTRIBUTE_SYNTAX:
+        message = "INVALID_ATTRIBUTE_SYNTAX";
+        break;
+      case NO_SUCH_OBJECT:
+        message = "NO_SUCH_OBJECT";
+        break;
+      case ALIAS_PROBLEM:
+        message = "ALIAS_PROBLEM";
+        break;
+      case INVALID_DN_SYNTAX:
+        message = "INVALID_DN_SYNTAX";
+        break;
+      case ALIAS_DEREFERENCING_PROBLEM:
+        message = "ALIAS_DEREFERENCING_PROBLEM";
+        break;
+      case INAPPROPRIATE_AUTHENTICATION:
+        message = "INAPPROPRIATE_AUTHENTICATION";
+        break;
+      case INVALID_CREDENTIALS:
+        message = "INVALID_CREDENTIALS";
+        break;
+      case INSUFFICIENT_ACCESS_RIGHTS:
+        message = "INSUFFICIENT_ACCESS_RIGHTS";
+        break;
+      case BUSY:
+        message = "BUSY";
+        break;
+      case UNAVAILABLE:
+        message = "UNAVAILABLE";
+        break;
+      case UNWILLING_TO_PERFORM:
+        message = "UNWILLING_TO_PERFORM";
+        break;
+      case LOOP_DETECT:
+        message = "LOOP_DETECT";
+        break;
+      case SORT_CONTROL_MISSING:
+        message = "SORT_CONTROL_MISSING";
+        break;
+      case OFFSET_RANGE_ERROR:
+        message = "OFFSET_RANGE_ERROR";
+        break;
+      case NAMING_VIOLATION:
+        message = "NAMING_VIOLATION";
+        break;
+      case OBJECTCLASS_VIOLATION:
+        message = "OBJECTCLASS_VIOLATION";
+        break;
+      case NOT_ALLOWED_ON_NONLEAF:
+        message = "NOT_ALLOWED_ON_NONLEAF";
+        break;
+      case NOT_ALLOWED_ON_RDN:
+        message = "NOT_ALLOWED_ON_RDN";
+        break;
+      case ENTRY_ALREADY_EXISTS:
+        message = "ENTRY_ALREADY_EXISTS";
+        break;
+      case OBJECTCLASS_MODS_PROHIBITED:
+        message = "OBJECTCLASS_MODS_PROHIBITED";
+        break;
+      case AFFECTS_MULTIPLE_DSAS:
+        message = "AFFECTS_MULTIPLE_DSAS";
+        break;
+      case VIRTUAL_LIST_VIEW_ERROR:
+        message = "VIRTUAL_LIST_VIEW_ERROR";
+        break;
+      case CLIENT_SIDE_SERVER_DOWN:
+        message = "CLIENT_SIDE_SERVER_DOWN";
+        break;
+      case CLIENT_SIDE_LOCAL_ERROR:
+        message = "CLIENT_SIDE_LOCAL_ERROR";
+        break;
+      case CLIENT_SIDE_ENCODING_ERROR:
+        message = "CLIENT_SIDE_ENCODING_ERROR";
+        break;
+      case CLIENT_SIDE_DECODING_ERROR:
+        message = "CLIENT_SIDE_DECODING_ERROR";
+        break;
+      case CLIENT_SIDE_TIMEOUT:
+        message = "CLIENT_SIDE_TIMEOUT";
+        break;
+      case CLIENT_SIDE_AUTH_UNKNOWN:
+        message = "CLIENT_SIDE_AUTH_UNKNOWN";
+        break;
+      case CLIENT_SIDE_FILTER_ERROR:
+        message = "CLIENT_SIDE_FILTER_ERROR";
+        break;
+      case CLIENT_SIDE_USER_CANCELLED:
+        message = "CLIENT_SIDE_USER_CANCELLED";
+        break;
+      case CLIENT_SIDE_PARAM_ERROR:
+        message = "CLIENT_SIDE_PARAM_ERROR";
+        break;
+      case CLIENT_SIDE_NO_MEMORY:
+        message = "CLIENT_SIDE_NO_MEMORY";
+        break;
+      case CLIENT_SIDE_CONNECT_ERROR:
+        message = "CLIENT_SIDE_CONNECT_ERROR";
+        break;
+      case CLIENT_SIDE_NOT_SUPPORTED:
+        message = "CLIENT_SIDE_NOT_SUPPORTED";
+        break;
+      case CLIENT_SIDE_CONTROL_NOT_FOUND:
+        message = "CLIENT_SIDE_CONTROL_NOT_FOUND";
+        break;
+      case CLIENT_SIDE_NO_RESULTS_RETURNED:
+        message = "CLIENT_SIDE_NO_RESULTS_RETURNED";
+        break;
+      case CLIENT_SIDE_MORE_RESULTS_TO_RETURN:
+        message = "CLIENT_SIDE_MORE_RESULTS_TO_RETURN";
+        break;
+      case CLIENT_SIDE_CLIENT_LOOP:
+        message = "CLIENT_SIDE_CLIENT_LOOP";
+        break;
+      case CLIENT_SIDE_REFERRAL_LIMIT_EXCEEDED:
+        message = "CLIENT_SIDE_REFERRAL_LIMIT_EXCEEDED";
+        break;
+      case CANCELED:
+        message = "CANCELED";
+        break;
+      case NO_SUCH_OPERATION:
+        message = "NO_SUCH_OPERATION";
+        break;
+      case TOO_LATE:
+        message = "TOO_LATE";
+        break;
+      case CANNOT_CANCEL:
+        message = "CANNOT_CANCEL";
+        break;
+      case ASSERTION_FAILED:
+        message = "ASSERTION_FAILED";
+        break;
+      case AUTHORIZATION_DENIED:
+        message = "AUTHORIZATION_DENIED";
+        break;
+      case NO_OPERATION:
+        message = "NO_OPERATION";
+        break;
+      default:
+        message = "OTHER";
+        break;
+    }
+
+    return message;
+  }
+}
+
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/ResponseChecker.java b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/ResponseChecker.java
new file mode 100644
index 0000000..1eb18c1
--- /dev/null
+++ b/opendj-sdk/opends/tests/staf-tests/shared/dsml/src/com/ibm/staf/service/opends/tester/ResponseChecker.java
@@ -0,0 +1,152 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/proctor/resource/legal-notices/Proctor.LICENSE
+ * or https://proctor.dev.java.net/Proctor.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package com.ibm.staf.service.opends.tester;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPMessage;
+import org.opends.dsml.protocol.BatchResponse;
+
+public class ResponseChecker {
+
+    private Map<String, String> header = new HashMap<String, String>();
+    private String httpCode;
+    private BatchResponse batchResponse;
+    private String body;
+    public ResponseChecker(String response) throws Exception {
+        this(new StringReader(response));
+
+    }
+
+    public ResponseChecker(Reader response) throws Exception {
+
+        // this.source = new StringBuilder();
+        boolean headerDone = false;
+        String line = null;
+        BufferedReader reader = new BufferedReader(response);
+        StringBuilder sb = new StringBuilder();
+
+        // assign first line of header to httpCode
+        // then assign all header to <key>:<value> to header map
+        // finally fill sb with body of request
+        while ((line = reader.readLine()) != null) {
+            if (!headerDone) {
+                if (line.length() == 0) {
+                    headerDone = true;
+                }
+                if (!headerDone) {
+                    if (httpCode == null) {
+                        httpCode = line;
+                    } else {
+                        String[] entry = line.split(":");
+                        header.put(entry[0].trim().toLowerCase(), entry[1].trim());
+                    }
+                }
+            } else {
+                sb.append(line);
+            }
+        }
+        this.body = sb.toString();
+
+        if (httpCode != null) {
+            if (httpCode.split(" ")[1].equals("200")) {
+
+                // reconstruct header for SOAP engine
+                MimeHeaders mimeHeaders = new MimeHeaders();
+                for (Map.Entry<String, String> entry : header.entrySet()) {
+                    String name = entry.getKey();
+                    String value = entry.getValue();
+                    StringTokenizer token = new StringTokenizer(value, ",");
+                    while (token.hasMoreTokens()) {
+                        mimeHeaders.addHeader(name, token.nextToken().trim());
+                    }
+                }
+                MessageFactory messageFactory = MessageFactory.newInstance();
+                SOAPMessage message = messageFactory.createMessage(mimeHeaders, new ByteArrayInputStream(this.body.getBytes()));
+
+                //DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                //dbf.setNamespaceAware(true);
+                //DocumentBuilder db = dbf.newDocumentBuilder();
+                //Document doc = db.newDocument();
+                SOAPBody soapBody = message.getSOAPBody();
+
+                Iterator iterator = soapBody.getChildElements();
+                while (iterator.hasNext()) {
+                    Object object = iterator.next();
+                    if (!(object instanceof SOAPElement)) {
+                        continue;
+                    }
+                    SOAPElement soapElement = (SOAPElement) object;
+
+                    JAXBContext jaxbContext = JAXBContext.newInstance(BatchResponse.class);
+                    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+                    JAXBElement<BatchResponse> batchResponseElement = unmarshaller.unmarshal(soapElement, BatchResponse.class);
+
+                    this.batchResponse = batchResponseElement.getValue();
+                }
+            }
+        }
+
+    }
+   
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof ResponseChecker)) {
+            return false;
+        }
+        ResponseChecker other = (ResponseChecker) o;
+
+        // check code "HTTP/1.1 200 OK".split(" ")[1] = "200"
+        if (!this.httpCode.split(" ")[1].equals(other.httpCode.split(" ")[1])) {
+            return false;
+        }
+
+        if (!Checker.equals(batchResponse, other.batchResponse)) {
+            return false;
+        }
+
+        return true;
+    }
+}
+
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/functions/stafcmd.xml b/opendj-sdk/opends/tests/staf-tests/shared/functions/stafcmd.xml
index ad0fae9..0e4a90c 100755
--- a/opendj-sdk/opends/tests/staf-tests/shared/functions/stafcmd.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/functions/stafcmd.xml
@@ -23,7 +23,7 @@
  !
  ! CDDL HEADER END
  !
- !      Copyright 2007-2008 Sun Microsystems, Inc.
+ !      Copyright 2007-2009 Sun Microsystems, Inc.
  ! -->
 <stax>
   <function name="copyFile">
@@ -73,7 +73,7 @@
       <return>[cmdRC,cmdResult]</return>
     </sequence>
   </function>
-    
+
   <function name="CopyFolderByExtension">
     <function-prolog>
       Copies files by extension from a source to destination folder on host
@@ -90,6 +90,60 @@
           The name of remote host (default same as location)
         </function-arg-description>
         <function-arg-property name="type" value="hostname"/>
+      </function-arg-def>
+      <function-arg-def name="srcfolder" type="required">
+        <function-arg-description>
+          The name of the source folder
+        </function-arg-description>
+        <function-arg-property name="type" value="foldername"/>
+      </function-arg-def>
+      <function-arg-def name="destfolder" type="required">
+        <function-arg-description>
+          The name of the destination file
+        </function-arg-description>
+        <function-arg-property name="type" value="foldername"/>
+      </function-arg-def>
+      <function-arg-def name="extension" type="optional" default="'txt'">
+        <function-arg-description>
+          The name of the file extension (default txt)
+        </function-arg-description>
+        <function-arg-property name="type" value="file extension"/>
+      </function-arg-def>
+    </function-map-args>
+    <sequence>
+      <stafcmd name="'STAF Command: Copy all %s Files.' % (extension)">
+        <location>'%s' % location</location>
+        <service>'fs'</service>
+        <request>'COPY DIRECTORY %s TODIRECTORY %s TOMACHINE %s EXT %s RECURSE' % (srcfolder,destfolder,remotehost,extension) </request>
+      </stafcmd>
+      <script>
+        cmdRC=RC
+        cmdResult=STAFResult
+      </script>
+      <call function="'checkRC'">
+        { 'returncode' : cmdRC ,
+          'result'     : cmdResult }
+      </call>
+      <return>cmdRC</return>
+    </sequence>
+  </function>
+
+  <function name="copyFolder">
+    <function-prolog>
+      Copies folder from a source to destination folder on host
+    </function-prolog>
+    <function-map-args>
+     <function-arg-def name="location" type="optional" default="STAXServiceMachine">
+        <function-arg-description>
+          Location of target host
+        </function-arg-description>
+        <function-arg-property name="type" value="hostname"/>
+      </function-arg-def>
+      <function-arg-def name="remotehost" type="optional" default="location">
+        <function-arg-description>
+          The name of remote host (default same as location)
+        </function-arg-description>
+        <function-arg-property name="type" value="hostname"/>
       </function-arg-def>        
       <function-arg-def name="srcfolder" type="required">
         <function-arg-description>
@@ -103,18 +157,12 @@
         </function-arg-description>
         <function-arg-property name="type" value="foldername"/>
       </function-arg-def>
-      <function-arg-def name="extension" type="optional" default="'txt'">
-        <function-arg-description>
-          The name of the file extension (default txt)
-        </function-arg-description>
-        <function-arg-property name="type" value="file extension"/>
-      </function-arg-def>
     </function-map-args>
     <sequence>
-      <stafcmd name="'STAF Command: Copy all %s Files.' % (extension)">
+      <stafcmd name="'STAF Command: Copy %s folder to %s.' % (srcfolder,destfolder)">
         <location>'%s' % location</location>
         <service>'fs'</service>
-        <request>'COPY DIRECTORY %s TODIRECTORY %s TOMACHINE %s EXT %s RECURSE' % (srcfolder,destfolder,remotehost,extension) </request>
+        <request>'COPY DIRECTORY %s TODIRECTORY %s TOMACHINE %s RECURSE' % (srcfolder,destfolder,remotehost) </request>
       </stafcmd>
       <script>
         cmdRC=RC
@@ -200,6 +248,18 @@
         </function-arg-description>
         <function-arg-property name="type" value="filename"/>
       </function-arg-def>
+      <function-arg-def name="file" type="optional" default="None">
+        <function-arg-description>
+          Name of file to unzip
+        </function-arg-description>
+        <function-arg-property name="type" value="filepath"/>
+      </function-arg-def>
+      <function-arg-def name="directory" type="optional" default="None">
+        <function-arg-description>
+          Name of directory to unzip
+        </function-arg-description>
+        <function-arg-property name="type" value="filepath"/>
+      </function-arg-def>
       <function-arg-def name="unzipdir" type="required">
         <function-arg-description>
           Name of destination folder to place zip file contents
@@ -209,11 +269,23 @@
     </function-map-args>
 
     <sequence>
+      <script>
+        if file:
+          file='FILE %s' % file
+        else:
+          file=''
+
+        if directory:
+          dir='DIRECTORY %s' % directory
+        else:
+          dir=''
+      </script>
+
       <stafcmd name="'STAF Command: Unzip File'">
         <location>'%s' % location</location>
         <service>'zip'</service>
         <request>
-            'UNZIP ZIPFILE %s TODIRECTORY %s RESTOREPERMISSION REPLACE' % (zipfile,unzipdir)
+            'UNZIP ZIPFILE %s TODIRECTORY %s %s %s RESTOREPERMISSION REPLACE' % (zipfile,unzipdir,file,dir)
         </request>
       </stafcmd>
       <script>
@@ -376,7 +448,7 @@
       </function-arg-def>
       <function-arg-def name="foldername" type="required">
         <function-arg-description>
-          Name of file to be deleted
+          Name of folder to be created
         </function-arg-description>
         <function-arg-property name="type" value="filepath"/>
       </function-arg-def>      
@@ -714,7 +786,7 @@
       <stafcmd name="'STAF Command: list folder by extension'">
         <location>'%s' % location</location>
         <service>'fs'</service>
-        <request>' LIST DIRECTORY %s EXT %s ' % (foldername,extension)</request>
+        <request>' LIST DIRECTORY %s EXT %s RECURSE' % (foldername,extension)</request>
       </stafcmd>
       
       <script>
@@ -884,5 +956,131 @@
       </stafcmd>
     </sequence>
   </function>
-  
+
+  <!-- Add STAF Java Service -->
+  <function name="addSTAFJavaService" scope="local">
+    <function-prolog>
+      Add STAF Java Service.
+    </function-prolog>
+    <function-map-args>
+      <function-arg-def name="location"
+                        type="optional"
+                        default="STAXServiceMachine">
+        <function-arg-description>
+          Location of target host
+        </function-arg-description>
+        <function-arg-property name="type" value="hostname"/>
+      </function-arg-def>
+      <function-arg-def name="serviceName" type="required">
+        <function-arg-description>
+          Name of the service to add
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+      <function-arg-def name="serviceJar" type="required">
+        <function-arg-description>
+          Jar of the service to add
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+      <function-arg-def name="JVM" type="optional" default="True">
+        <function-arg-description>
+          JVM path
+        </function-arg-description>
+        <function-arg-property name="type" value="enum"/>
+      </function-arg-def>
+      <function-arg-def name="J2" type="optional">
+        <function-arg-description>
+          JVM options
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+    </function-map-args>
+
+    <sequence>
+
+      <message>
+        'Check if STAF Java Service %s is already started on %s' \
+        % (serviceName, location)
+      </message>
+      <stafcmd name="'STAF Command: Check STAF Java Service.'">
+        <location>'%s' % location</location>
+        <service>'service'</service>
+        <request>'query service %s' % serviceName</request>
+      </stafcmd>
+      <if expr="RC == 48">
+        <sequence>
+          <script>
+            cmdOptions = 'ADD SERVICE %s LIBRARY JSTAF' % serviceName
+            cmdOptions += ' EXECUTE %s' % serviceJar
+
+            if JVM:
+              cmdOptions += ' OPTION JVMNAME=%sJVM-%s' % (serviceName,location)
+
+              if location == STAXServiceMachine:
+                cmdOptions += ' OPTION JVM=%s/bin/java' % LOCAL_JAVA_HOME
+              else:
+                cmdOptions += ' OPTION JVM=%s/bin/java' % JAVA_HOME
+
+              if J2:
+                cmdOptions += ' OPTION J2="%s"' % J2
+          </script>
+
+          <message>
+            'Add STAF Java Service %s on %s' % (serviceName, location)
+          </message>
+          <message>'service %s' % cmdOptions</message>
+          <stafcmd name="'STAF Command: Add STAF Java Service.'">
+            <location>'%s' % location</location>
+            <service>'service'</service>
+            <request>'%s' % cmdOptions</request>
+          </stafcmd>
+        </sequence>
+        <else>
+          <message>
+            'STAF Java Service %s is already started on %s' \
+            % (serviceName, location)
+          </message>
+        </else>
+      </if>
+    </sequence>
+  </function>
+
+  <!-- Remove STAF Java Service -->
+  <function name="removeSTAFJavaService" scope="local">
+    <function-prolog>
+      Remove STAF Java Service.
+    </function-prolog>
+    <function-map-args>
+      <function-arg-def name="location"
+                        type="optional"
+                        default="STAXServiceMachine">
+        <function-arg-description>
+          Location of target host
+        </function-arg-description>
+        <function-arg-property name="type" value="hostname"/>
+      </function-arg-def>
+      <function-arg-def name="serviceName" type="required">
+        <function-arg-description>
+          Name of the service to add
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+    </function-map-args>
+
+    <sequence>
+      <script>
+        cmdOptions = 'REMOVE SERVICE %s ' % serviceName
+      </script>
+
+      <message>
+        'Remove STAF Java Service %s on %s' % (serviceName, location)
+      </message>
+      <stafcmd name="'STAF Command: Remove STAF Java Service.'">
+        <location>'%s' % location</location>
+        <service>'service'</service>
+        <request>'%s' % cmdOptions</request>
+      </stafcmd>
+    </sequence>
+  </function>
 </stax>
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/functions/utils.xml b/opendj-sdk/opends/tests/staf-tests/shared/functions/utils.xml
index d5c6f45..3a211e6 100755
--- a/opendj-sdk/opends/tests/staf-tests/shared/functions/utils.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/functions/utils.xml
@@ -2387,12 +2387,18 @@
         </function-arg-description>
         <function-arg-property name="type" value="hostname"/>
       </function-arg-def>
-      <function-arg-def name="foldername" type="required">
+      <function-arg-def name="foldername" type="optional">
         <function-arg-description>
           Path containing java files to compile
         </function-arg-description>
         <function-arg-property name="type" value="filepath"/>
       </function-arg-def>
+      <function-arg-def name="destfolder" type="optional">
+        <function-arg-description>
+          Path where to place generated class files
+        </function-arg-description>
+        <function-arg-property name="type" value="filepath"/>
+      </function-arg-def>
       <function-arg-def name="classpath" type="optional">
         <function-arg-description>
           Additional classpath
@@ -2401,8 +2407,7 @@
       </function-arg-def>      
       <function-arg-def name="expectedRC" type="optional" default="0">
         <function-arg-description>
-          Expected return code value.
-          0 for successful grep, 1 for unsuccessful grep. Default value is 0.
+          Expected return code value. Default value is 0.
           Wildcard 'noCheck' to not check the RC
         </function-arg-description>
       </function-arg-def>   
@@ -2412,6 +2417,8 @@
 
       <!-- Build the command -->
       <script>
+        cmdOptions = ''
+
         if is_windows_platform(location):
           separator=';'
         else:
@@ -2428,6 +2435,9 @@
         else:
           cmd = '%s/bin/javac' % JAVA_HOME
           env = ['JAVA_HOME=%s' % JAVA_HOME, '%s' % cp]
+
+        if destfolder:
+          cmdOptions = '-d %s' % destfolder
       </script>
 
       <call function="'listFolderByExtension'" >
@@ -2454,7 +2464,7 @@
             { 
             'name'       : 'Compile Java files' ,
             'command'    : cmd ,
-            'arguments'  : '-target 1.5 %s' % list ,
+            'arguments'  : '-target 1.5 %s %s' % (cmdOptions,list) ,
             'location'   : location ,
             'path'       : foldername ,
             'envCmd'     : env ,
@@ -2473,6 +2483,98 @@
     </sequence>
   </function>
 
+  <function name="createJar" scope="local">
+    <function-prolog>
+      This function create a jar file.
+    </function-prolog>
+    <function-map-args>
+      <function-arg-def name="location"
+                        type="optional"
+                        default="STAXServiceMachine">
+        <function-arg-description>
+          Location of remote host
+        </function-arg-description>
+        <function-arg-property name="type" value="hostname"/>
+      </function-arg-def>
+      <function-arg-def name="jarname" type="required">
+        <function-arg-description>
+          Name of the jar file to create
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+      <function-arg-def name="entrypoint" type="required">
+        <function-arg-description>
+          Path where to find generated class files
+        </function-arg-description>
+        <function-arg-property name="type" value="string"/>
+      </function-arg-def>
+      <function-arg-def name="pathfolder" type="required">
+        <function-arg-description>
+          Execution path
+        </function-arg-description>
+        <function-arg-property name="type" value="filepath"/>
+      </function-arg-def>
+      <function-arg-def name="manifestpath" type="optional">
+        <function-arg-description>
+          Path to the manifest file
+        </function-arg-description>
+        <function-arg-property name="type" value="filepath"/>
+      </function-arg-def>
+      <function-arg-def name="expectedRC" type="optional" default="0">
+        <function-arg-description>
+          Expected return code value. Default value is 0.
+          Wildcard 'noCheck' to not check the RC
+        </function-arg-description>
+      </function-arg-def>
+    </function-map-args>
+
+    <sequence>
+
+      <!-- Build the command -->
+      <script>
+        if location == STAXServiceMachine:
+          cmd = '%s/bin/jar' % LOCAL_JAVA_HOME
+        else:
+          cmd = '%s/bin/jar' % JAVA_HOME
+
+        if manifestpath:
+          cmdOptions = 'cmf %s' % manifestpath
+        else:
+          cmdOptions = 'cf'
+      </script>
+
+      <!-- Check if the classfolder exists -->
+      <call function="'GetEntry'">
+        {
+        'location'  : location ,
+        'entry'     : '%s/%s' % (pathfolder,entrypoint) ,
+        'attribute' : 'TYPE'
+        }
+      </call>
+      <if expr="RC != 48">
+        <sequence>
+          <call function="'runCommand'" >
+            {
+            'name'       : 'Create Jar file' ,
+            'command'    : cmd ,
+            'arguments'  : '%s %s %s' % (cmdOptions,jarname,entrypoint) ,
+            'location'   : location ,
+            'path'       : pathfolder ,
+            'expectedRC' : expectedRC
+            }
+          </call>
+        </sequence>
+        <else>
+          <tcstatus result="'fail'"></tcstatus>
+        </else>
+      </if>
+
+      <return>
+        STAXResult
+      </return>
+    </sequence>
+  </function>
+
   <function name="getFreePort" scope="local">
     <function-description>
       Returns the first free TCP port greater or equal to given number
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/functions/webcontainer.xml b/opendj-sdk/opends/tests/staf-tests/shared/functions/webcontainer.xml
index 104c05e..3ec0c2d 100755
--- a/opendj-sdk/opends/tests/staf-tests/shared/functions/webcontainer.xml
+++ b/opendj-sdk/opends/tests/staf-tests/shared/functions/webcontainer.xml
@@ -106,7 +106,7 @@
         <call function="'GetEntry'">
           {
           'location'  : STAXServiceMachine,
-          'entry'     : '%s/services/DSML/tomcatCertificate' % LOCAL_STAF_ROOT,
+          'entry'     : '%s/tomcatCertificate' % TMPDIR,
           'attribute' : 'TYPE'
           }
         </call>
@@ -118,9 +118,9 @@
               'command'   : '%s/bin/keytool' % (LOCAL_JAVA_HOME),
               'arguments' : '-genkey -alias tomcat -keyalg rsa \
                              -dname "cn=tomcat,O=Sun Microsystems,C=US" \
-                             -keystore "%s/services/DSML/tomcatCertificate" \
+                             -keystore "%s/tomcatCertificate" \
                              -storepass "changeit" -keypass "changeit" \
-                             -storetype JKS ' % (LOCAL_STAF_ROOT),
+                             -storetype JKS ' % (TMPDIR),
               'path'      : '%s/bin' % (LOCAL_JAVA_HOME),
               'expectedRC': 0
             }
@@ -129,7 +129,7 @@
 
         <call function="'copyFile'">
           { 'location'   : STAXServiceMachine,
-            'srcfile'    : '%s/services/DSML/tomcatCertificate' % (LOCAL_STAF_ROOT),
+            'srcfile'    : '%s/tomcatCertificate' % (TMPDIR),
             'destfile'   : '%s/%s-%s/conf/tomcatCertificate' % (wcPath, WC_TYPE, WC_VERSION),
             'remotehost' : mylocation
           }
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/staf/staf-controller.cfg b/opendj-sdk/opends/tests/staf-tests/shared/staf/staf-controller.cfg
index 02075df..d757975 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/staf/staf-controller.cfg
+++ b/opendj-sdk/opends/tests/staf-tests/shared/staf/staf-controller.cfg
@@ -47,39 +47,35 @@
 
 # STAX SERVICE CONFIGURATION
 SERVICE Stax LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/stax/STAX.jar \
-  OPTION J2="-Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -XX:NewSize=500m -XX:MaxNewSize=500m -XX:SurvivorRatio=6 -XX:PermSize=256m -XX:MaxPermSize=256m -Xoss1m -Xss1m" \
+  EXECUTE ${staf.install.dir}/${stax.name}/STAX.jar \
+  OPTION JVMNAME=stafJVM-${local.hostname}  \
+  OPTION J2=-Xms1g -Xmx1g \
+    -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled \
+    -XX:+CMSPermGenSweepingEnabled -XX:NewSize=500m -XX:MaxNewSize=500m \
+    -XX:SurvivorRatio=6 -XX:PermSize=256m -XX:MaxPermSize=256m -Xoss2m -Xss2m \
   OPTION JVM=${local.javahome}/bin/java \
   PARMS "PYTHONOUTPUT JobUserLogAndMsg" "PYTHONLOGLEVEL Info"
 
 # EVENT SERVICE CONFIGURATION
 SERVICE Event LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/event/STAFEvent.jar
+  EXECUTE ${staf.install.dir}/${event.name}/STAFEvent.jar
 
 # EVENTMANAGER SERVICE CONFIGURATION
 SERVICE EventManager LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/eventmanager/STAFEventManager.jar
+  EXECUTE ${staf.install.dir}/${eventmanager.name}/STAFEventManager.jar
 
 # EMAIL SERVICE CONFIGURATION
 SERVICE Email LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/email/STAFEmail.jar \
+  EXECUTE ${staf.install.dir}/${email.name}/STAFEmail.jar \
   PARMS "MAILSERVER ${email.server.host} PORT ${email.server.port}"
 
 SET MAXQUEUESIZE 10000
 
 # HTTP SERVICE CONFIGURATION
 SERVICE Http LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/http/STAFHTTP.jar \
-  OPTION JVMNAME=httpJVM  \
-  OPTION J2=-Xmx128m -Xms32m \
+  EXECUTE ${staf.install.dir}/${http.name}/STAFHTTP.jar \
+  OPTION JVMNAME=httpJVM-${local.hostname}  \
+  OPTION J2=-Xms32m -Xmx128m \
     -Djavax.net.ssl.trustStorePassword=changeit \
-    -Djavax.net.ssl.trustStore={STAF/Config/STAFRoot}/services/DSML/tomcatCertificate \
+    -Djavax.net.ssl.trustStore=${temp.dir}/tomcatCertificate \
   OPTION JVM=${local.javahome}/bin/java
-
-# DSML SERVICE CONFIGURATION
-SERVICE Dsml LIBRARY JSTAF \
-  EXECUTE {STAF/Config/STAFRoot}/services/DSML/dsmlService.jar \
-  OPTION JVMNAME=dsmlJVM \
-  OPTION J2=-Xmx512m -Xms128m \
-  OPTION JVM=${local.javahome}/bin/java
-
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/stax.dtd b/opendj-sdk/opends/tests/staf-tests/shared/stax.dtd
index 75458da..0ea3208 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/stax.dtd
+++ b/opendj-sdk/opends/tests/staf-tests/shared/stax.dtd
@@ -27,7 +27,7 @@
 <!--
    STAf eXecution (STAX) Document Type Definition (DTD)
 
-   Generated Date: 20090312-15:22:34
+   Generated Date: 20090818-11:49:53
 
    This DTD module is identified by the SYSTEM identifier:
 
@@ -39,17 +39,17 @@
 
 <!ENTITY % stax-elems 'function | script | signalhandler'>
 
-<!ENTITY % task       'call | terminate | raise | 
-                       block | iterate | throw | 
-                       break | paralleliterate | timer | 
-                       if | loop | import | 
-                       tcstatus | rethrow | parallel | 
-                       hold | return | job | 
-                       call-with-list | script | log | 
-                       stafcmd | nop | testcase | 
-                       message | process | signalhandler | 
-                       call-with-map | sequence | continue | 
-                       release | try'>
+<!ENTITY % task       'timer | parallel | log | 
+                       call | stafcmd | script | 
+                       tcstatus | message | iterate | 
+                       sequence | import | raise | 
+                       job | process | nop | 
+                       try | break | testcase | 
+                       paralleliterate | continue | throw | 
+                       release | signalhandler | rethrow | 
+                       block | hold | terminate | 
+                       return | if | call-with-list | 
+                       loop | call-with-map'>
 
 <!--================= STAX Job Definition ========================== -->
 <!--
@@ -71,6 +71,64 @@
           function     IDREF    #REQUIRED
 >
 
+<!--================= The Timer Element ============================ -->
+<!--
+     The timer element runs a task for a specified duration.
+     If the task is still running at the end of the specified duration,
+     then the RC variable is set to 1, else if the task ended before
+     the specified duration, the RC variable is set to 0, else if the
+     timer could not start due to an invalid duration, the RC variable
+     is set to -1.
+-->
+<!ELEMENT timer     (%task;)>
+<!-- duration is the maximum length of time to run the task.
+       Time can be expressed in milliseconds, seconds, minutes,
+       hours, days, weeks, or years.  It is evaluated via Python.
+         Examples:  duration='50'    (50 milliseconds)
+                    duration='90s'   (90 seconds)
+                    duration='5m'    ( 5 minutes)
+                    duration='36h'   (36 hours)
+                    duration='3d'    ( 3 days)
+                    duration='1w'    ( 1 week)
+                    duration='1y'    ( 1 year)
+-->
+<!ATTLIST timer
+          duration   CDATA        #REQUIRED
+>
+
+<!--================= The Parallel Element ========================= -->
+<!--
+     The parallel element performs one or more tasks in parallel.
+-->
+<!ELEMENT parallel   (%task;)+>
+
+<!--================= The Log Element ============================== -->
+<!--
+     Writes a message and its log level to a STAX Job User Log file.
+     The message must evaluate via Python to a string.
+
+     The log level specified defaults to 'info'.  If specified, it
+     must evaluate via Python to a string containing one of the
+     following STAF Log Service Log levels:
+       fatal, warning, info, trace, trace2, trace3, debug, debug2,
+       debug3, start, stop, pass, fail, status, user1, user2, user3,
+       user4, user5, user6, user7, user8
+     The message attribute is evaluated via Python.  If it evaluates
+     to true, the message text will also be sent to the STAX Job Monitor.
+     The message attribute defaults to the STAXMessageLog variable whose
+     value defaults to 0 (false) but can by changed within the STAX job
+     to turn on messaging.
+
+     If an if attribute is specified and it evaluates via Python to
+     false, then the log element is ignored.
+-->
+<!ELEMENT log         (#PCDATA)>
+<!ATTLIST log
+          level       CDATA       "'info'"
+          message     CDATA       "STAXMessageLog"
+          if          CDATA       "1"
+>
+
 <!--================= The Call Element ============================= -->
 <!--
      Perform a function with the referenced name.
@@ -84,39 +142,84 @@
 >
 
 
-<!--================= The Terminate Element ======================== -->
+<!--================= The STAF Command Element ===================== -->
 <!--
-     The terminate element specifies to terminate a block in the job.
+     Specifies a STAF command to be executed.
+     Its name and all of its element values are evaluated via Python.
+-->
+<!ELEMENT stafcmd    (location, service, request)>
+<!ATTLIST stafcmd
+          name       CDATA   #IMPLIED
+>
+<!ELEMENT service    (#PCDATA)>
+<!ELEMENT request    (#PCDATA)>
+
+<!--================= The Script Element =========================== -->
+<!--
+     Specifies Python code to be executed.
+-->
+<!ELEMENT script     (#PCDATA)>
+
+<!--================= The Testcase Status Element ================== -->
+<!--
+     Marks status result ('pass' or 'fail' or 'info') for a testcase
+     and allows additional information to be specified.  The status
+     result and the additional info is evaluated via Python.
+-->
+<!ELEMENT tcstatus   (#PCDATA)>
+<!ATTLIST tcstatus
+          result     CDATA  #REQUIRED
+>
+
+<!--================= The Message Element ========================== -->
+<!--
+     Generates an event and makes the message value available to the
+     STAX Job Monitor.  The message must evaluate via Python to a string.
+
+     The log attribute is evaluated via Python to a boolean.  If it
+     evaluates to true, the message text will also be logged in the STAX
+     Job User log.  The log attribute defaults to the STAXLogMessage
+     variable whose value defaults to 0 (false) but can by changed within
+     the STAX job to turn on logging.
+
+     The log level is ignored if the log attribute does not evaluate to
+     true.  It defaults to 'info'.  If specified, it must evaluate via
+     Python to a string containing one of the following STAF Log Service
+     logging levels:
+       fatal, warning, info, trace, trace2, trace3, debug, debug2,
+       debug3, start, stop, pass, fail, status, user1, user2, user3,
+       user4, user5, user6, user7, user8
+
      If an if attribute is specified and it evaluates via Python to
-     false, the terminate element is ignored.
+     false, the message element is ignored.
 -->
-<!ELEMENT terminate  EMPTY>
-<!ATTLIST terminate
-          block      CDATA    #IMPLIED
-          if         CDATA    "1"
+<!ELEMENT message     (#PCDATA)>
+<!ATTLIST message
+          log         CDATA       "STAXLogMessage"
+          level       CDATA       "'info'"
+          if          CDATA       "1"
 >
 
-<!--================= The Raise Element ============================ -->
+<!--================= The Iterate Element ========================= -->
 <!--
-     A raise signal element raises a specified signal.
-     Signals can also be raised by the STAX execution engine.
-     The signal attribute value is evaluated via Python.
+     The iterate element iterates through a list of items, performing
+     its contained task while substituting each item in the list.
+     The iterated tasks are performed in sequence.
 -->
-<!ELEMENT raise      EMPTY>
-<!ATTLIST raise
-          signal     CDATA        #REQUIRED
->
-
-<!--================= The Block Element ============================ -->
-<!--
-     Defines a task block that can be held, released, or terminated.
-     Used in conjunction with the hold/terminate/release elements to
-     define a task block that can be held, terminated, or released.
-     The name attribute value is evaluated via Python.
+<!ELEMENT iterate  (%task;)>
+<!-- var      is the name of the variable which will contain the
+              current item in the list or tuple being iterated.
+              It is a literal.
+     in       is the list or tuple to be iterated.  It is evaluated
+              via Python and must evaluate to be a list or tuple.
+     indexvar is the name of a variable which will contain the index of
+              the current item in the list or tuple being iterated.
+              It is a literal.  The value for the first index is 0.
 -->
-<!ELEMENT block      (%task;)>
-<!ATTLIST block
-          name       CDATA    #REQUIRED
+<!ATTLIST iterate
+          var        CDATA    #REQUIRED
+          in         CDATA    #REQUIRED
+          indexvar   CDATA    #IMPLIED
 >
 
 <!--================= The Function Element ========================= -->
@@ -207,143 +310,11 @@
           value        CDATA    #IMPLIED
 >
 
-<!--================= The Iterate Element ========================= -->
+<!--================= The Sequence Element ========================= -->
 <!--
-     The iterate element iterates through a list of items, performing
-     its contained task while substituting each item in the list.
-     The iterated tasks are performed in sequence.
+     The sequence element performs one or more tasks in sequence.
 -->
-<!ELEMENT iterate  (%task;)>
-<!-- var      is the name of the variable which will contain the
-              current item in the list or tuple being iterated.
-              It is a literal.
-     in       is the list or tuple to be iterated.  It is evaluated
-              via Python and must evaluate to be a list or tuple.
-     indexvar is the name of a variable which will contain the index of
-              the current item in the list or tuple being iterated.
-              It is a literal.  The value for the first index is 0.
--->
-<!ATTLIST iterate
-          var        CDATA    #REQUIRED
-          in         CDATA    #REQUIRED
-          indexvar   CDATA    #IMPLIED
->
-
-<!--================= The Throw Element ============================ -->
-<!--
-     The throw element specifies an exception to throw.
-     The exception attribute value and any additional information
-     is evaluated via Python.
--->
-<!ELEMENT throw      (#PCDATA)>
-<!ATTLIST throw
-          exception  CDATA        #REQUIRED
->
-
-<!--================= Break Element ================================ -->
-<!--
-     The break element can be used to break out of a loop or iterate
-     element.
--->
-<!ELEMENT break      EMPTY>
-
-<!--================= The Parallel Iterate Element ================ -->
-<!--
-     The parallel iterate element iterates through a list of items,
-     performing its contained task while substituting each item in
-     the list.  The iterated tasks are performed in parallel.
--->
-<!ELEMENT paralleliterate  (%task;)>
-<!-- var      is the name of a variable which will contain the current
-              item in the list or tuple being iterated.
-              It is a literal.
-     in       is the list or tuple to be iterated.  It is evaluated
-              via Python and must evaluate to be a list or tuple.
-     indexvar is the name of a variable which will contain the index of
-              the current item in the list or tuple being iterated.
-              It is a literal.  The value of the first index is 0.
--->
-<!ATTLIST paralleliterate
-          var        CDATA    #REQUIRED
-          in         CDATA    #REQUIRED
-          indexvar   CDATA    #IMPLIED
->
-
-<!--================= The Timer Element ============================ -->
-<!--
-     The timer element runs a task for a specified duration.
-     If the task is still running at the end of the specified duration,
-     then the RC variable is set to 1, else if the task ended before
-     the specified duration, the RC variable is set to 0, else if the
-     timer could not start due to an invalid duration, the RC variable
-     is set to -1.
--->
-<!ELEMENT timer     (%task;)>
-<!-- duration is the maximum length of time to run the task.
-       Time can be expressed in milliseconds, seconds, minutes,
-       hours, days, weeks, or years.  It is evaluated via Python.
-         Examples:  duration='50'    (50 milliseconds)
-                    duration='90s'   (90 seconds)
-                    duration='5m'    ( 5 minutes)
-                    duration='36h'   (36 hours)
-                    duration='3d'    ( 3 days)
-                    duration='1w'    ( 1 week)
-                    duration='1y'    ( 1 year)
--->
-<!ATTLIST timer
-          duration   CDATA        #REQUIRED
->
-
-<!--================= The Conditional Element (if-then-else) ======= -->
-<!--
-     Allows you to write an if or a case construct with zero or more
-     elseifs and one or no else statements.
-
-     The expr attribute value is evaluated via Python and must evaluate
-     to a boolean value.
--->
-<!ELEMENT if         ((%task;), elseif*, else?)>
-<!ATTLIST if
-          expr       CDATA   #REQUIRED
->
-<!ELEMENT elseif     (%task;)>
-<!ATTLIST elseif
-          expr       CDATA   #REQUIRED
->
-<!ELEMENT else       (%task;)>
-
-<!--================= The Loop Element ============================= -->
-<!--
-     The loop element performs a task a specified number of times,
-     allowing specification of an upper and lower bound with an
-     increment value and where the index counter is available to
-     sub-tasks.  Also, while and/or until expressions can be
-     specified.
--->
-<!ELEMENT loop       (%task;)>
-<!-- var      is the name of a variable which will contain the loop
-              index variable.  It is a literal.
-     from     is the starting value of the loop index variable.
-              It must evaluate to an integer value via Python.
-     to       is the maximum value of the loop index variable
-              It must evaluate to an integer value via Python.
-     by       is the increment value for the loop index variable
-              It must evaluate to an integer value via Python.
-     while    is an expression that must evaluate to a boolean value
-              and is performed at the top of each loop.  If it
-              evaluates to false, it breaks out of the loop.
-     until    is an expression that must evaluate to a boolean value
-              and is performed at the bottom of each loop.  If it
-              evaluates to false, it breaks out of the loop.
--->
-<!ATTLIST loop
-          var        CDATA    #IMPLIED
-          from       CDATA    '1'
-          to         CDATA    #IMPLIED
-          by         CDATA    '1'
-          while      CDATA    #IMPLIED
-          until      CDATA    #IMPLIED
->
+<!ELEMENT sequence   (%task;)+>
 
 <!--================= The Import Element ========================== -->
 <!--
@@ -351,55 +322,25 @@
 -->
 <!ELEMENT import        (import-include?, import-exclude?)?>
 <!ATTLIST import
-          machine     CDATA       #REQUIRED
           file        CDATA       #REQUIRED
-          mode        CDATA         "'error'"
+          machine     CDATA       #IMPLIED
+          mode        CDATA       "'error'"
 >
 <!ELEMENT import-include          (#PCDATA)>
 <!ELEMENT import-exclude          (#PCDATA)>
 
 
-<!--================= The Testcase Status Element ================== -->
+<!--================= The Raise Element ============================ -->
 <!--
-     Marks status result ('pass' or 'fail' or 'info') for a testcase
-     and allows additional information to be specified.  The status
-     result and the additional info is evaluated via Python.
+     A raise signal element raises a specified signal.
+     Signals can also be raised by the STAX execution engine.
+     The signal attribute value is evaluated via Python.
 -->
-<!ELEMENT tcstatus   (#PCDATA)>
-<!ATTLIST tcstatus
-          result     CDATA  #REQUIRED
+<!ELEMENT raise      EMPTY>
+<!ATTLIST raise
+          signal     CDATA        #REQUIRED
 >
 
-<!--================= The Rethrow Element ========================= -->
-<!--
-     The rethrow element specifies to rethrow the current exception.
--->
-<!ELEMENT rethrow      EMPTY>
-
-<!--================= The Parallel Element ========================= -->
-<!--
-     The parallel element performs one or more tasks in parallel.
--->
-<!ELEMENT parallel   (%task;)+>
-
-<!--================= The Hold Element ============================= -->
-<!--
-     The hold element specifies to hold a block in the job.
-     If an if attribute is specified and it evaluates via Python to
-     false, the hold element is ignored.
--->
-<!ELEMENT hold       EMPTY>
-<!ATTLIST hold
-          block      CDATA    #IMPLIED
-          if         CDATA    "1"
->
-
-<!--================= The Return Element =========================== -->
-<!--
-     Specifies a value to return from a function.
--->
-<!ELEMENT return     (#PCDATA)>
-
 <!--================== The STAX Job Element ===================== -->
 <!--
      Specifies a STAX sub-job to be executed.  This element is equivalent
@@ -613,112 +554,6 @@
           if        CDATA    "1"
 >
 
-<!--================= The Call-With-List Element =================== -->
-<!--
-     Perform a function with the referenced name with any number of
-     arguments in the form of a list.  The function attribute value
-     and argument values are evaluated via Python.
--->
-<!ELEMENT call-with-list      (call-list-arg*)>
-<!ATTLIST call-with-list
-          function   CDATA    #REQUIRED
->
-
-<!ELEMENT call-list-arg       (#PCDATA)>
-
-
-<!--================= The Script Element =========================== -->
-<!--
-     Specifies Python code to be executed.
--->
-<!ELEMENT script     (#PCDATA)>
-
-<!--================= The Log Element ============================== -->
-<!--
-     Writes a message and its log level to a STAX Job User Log file.
-     The message must evaluate via Python to a string.
-
-     The log level specified defaults to 'info'.  If specified, it
-     must evaluate via Python to a string containing one of the
-     following STAF Log Service Log levels:
-       fatal, warning, info, trace, trace2, trace3, debug, debug2,
-       debug3, start, stop, pass, fail, status, user1, user2, user3,
-       user4, user5, user6, user7, user8
-     The message attribute is evaluated via Python.  If it evaluates
-     to true, the message text will also be sent to the STAX Job Monitor.
-     The message attribute defaults to the STAXMessageLog variable whose
-     value defaults to 0 (false) but can by changed within the STAX job
-     to turn on messaging.
-
-     If an if attribute is specified and it evaluates via Python to
-     false, then the log element is ignored.
--->
-<!ELEMENT log         (#PCDATA)>
-<!ATTLIST log
-          level       CDATA       "'info'"
-          message     CDATA       "STAXMessageLog"
-          if          CDATA       "1"
->
-
-<!--================= The STAF Command Element ===================== -->
-<!--
-     Specifies a STAF command to be executed.
-     Its name and all of its element values are evaluated via Python.
--->
-<!ELEMENT stafcmd    (location, service, request)>
-<!ATTLIST stafcmd
-          name       CDATA   #IMPLIED
->
-<!ELEMENT service    (#PCDATA)>
-<!ELEMENT request    (#PCDATA)>
-
-<!--================= The No Operation Element ===================== -->
-<!--
-     No operation action.
--->
-<!ELEMENT nop        EMPTY>
-
-<!--================= The Testcase Element ========================= -->
-<!--
-     Defines a testcase.  Used in conjunction with the tcstatus
-     element to mark the status for a testcase.
-     The name attribute value is evaluated via Python.
--->
-<!ELEMENT testcase   (%task;)>
-<!ATTLIST testcase
-          name       CDATA    #REQUIRED
-          mode       CDATA    "'default'"
->
-
-<!--================= The Message Element ========================== -->
-<!--
-     Generates an event and makes the message value available to the
-     STAX Job Monitor.  The message must evaluate via Python to a string.
-
-     The log attribute is evaluated via Python to a boolean.  If it
-     evaluates to true, the message text will also be logged in the STAX
-     Job User log.  The log attribute defaults to the STAXLogMessage
-     variable whose value defaults to 0 (false) but can by changed within
-     the STAX job to turn on logging.
-
-     The log level is ignored if the log attribute does not evaluate to
-     true.  It defaults to 'info'.  If specified, it must evaluate via
-     Python to a string containing one of the following STAF Log Service
-     logging levels:
-       fatal, warning, info, trace, trace2, trace3, debug, debug2,
-       debug3, start, stop, pass, fail, status, user1, user2, user3,
-       user4, user5, user6, user7, user8
-
-     If an if attribute is specified and it evaluates via Python to
-     false, the message element is ignored.
--->
-<!ELEMENT message     (#PCDATA)>
-<!ATTLIST message
-          log         CDATA       "STAXLogMessage"
-          level       CDATA       "'info'"
-          if          CDATA       "1"
->
-
 <!--================= The STAF Process Element ===================== -->
 <!--
      Specifies a STAF process to be started.
@@ -1112,6 +947,110 @@
           if        CDATA     "1"
 >
 
+<!--================= The No Operation Element ===================== -->
+<!--
+     No operation action.
+-->
+<!ELEMENT nop        EMPTY>
+
+<!--=============== The Try / Catch / Finally Elements ============= --> 
+<!-- 
+     The try element allows you to perform a task and to catch 
+     exceptions that are thrown.  Also, if a finally element is 
+     specified, then the finally task is executed, no matter whether 
+     the try task completes normally or abruptly, and no matter whether 
+     a catch element is first given control. 
+--> 
+<!ELEMENT try        ((%task;), ((catch+) | ((catch*), finally)))> 
+<!-- 
+     The catch element performs a task when the specified exception is 
+     caught.  The var attribute specifies the name of the variable to 
+     receive the data specified within the throw element.  The typevar 
+     attribute specifies the name of the variable to receive the type 
+     of the exception.  The sourcevar attribute specifies the name
+     of the variable to receive the source information for the exception.
+ 
+--> 
+<!ELEMENT catch      (%task;)> 
+<!ATTLIST catch 
+          exception  CDATA        #REQUIRED 
+          var        CDATA        #IMPLIED 
+          typevar    CDATA        #IMPLIED 
+          sourcevar  CDATA        #IMPLIED 
+> 
+<!ELEMENT finally    (%task;)> 
+
+<!--================= Break Element ================================ -->
+<!--
+     The break element can be used to break out of a loop or iterate
+     element.
+-->
+<!ELEMENT break      EMPTY>
+
+<!--================= The Testcase Element ========================= -->
+<!--
+     Defines a testcase.  Used in conjunction with the tcstatus
+     element to mark the status for a testcase.
+     The name attribute value is evaluated via Python.
+-->
+<!ELEMENT testcase   (%task;)>
+<!ATTLIST testcase
+          name       CDATA    #REQUIRED
+          mode       CDATA    "'default'"
+>
+
+<!--================= The Parallel Iterate Element ================ -->
+<!--
+     The parallel iterate element iterates through a list of items,
+     performing its contained task while substituting each item in
+     the list.  The iterated tasks are performed in parallel.
+-->
+<!ELEMENT paralleliterate  (%task;)>
+<!-- var      is the name of a variable which will contain the current
+              item in the list or tuple being iterated.
+              It is a literal.
+     in       is the list or tuple to be iterated.  It is evaluated
+              via Python and must evaluate to be a list or tuple.
+     indexvar is the name of a variable which will contain the index of
+              the current item in the list or tuple being iterated.
+              It is a literal.  The value of the first index is 0.
+-->
+<!ATTLIST paralleliterate
+          var        CDATA    #REQUIRED
+          in         CDATA    #REQUIRED
+          indexvar   CDATA    #IMPLIED
+>
+
+<!--================= Continue Element ============================= -->
+<!--
+     The continue element can be used to continue to the top of a loop
+     or iterate element.
+-->
+<!ELEMENT continue   EMPTY>
+
+<!--================= The Throw Element ============================ -->
+<!--
+     The throw element specifies an exception to throw.
+     The exception attribute value and any additional information
+     is evaluated via Python.
+-->
+<!ELEMENT throw      (#PCDATA)>
+<!ATTLIST throw
+          exception  CDATA        #REQUIRED
+>
+
+<!--================= The Release Element ========================== -->
+<!--
+     The release element specifies to release a block in the job.
+     If an if attribute is specified and it evaluates via Python to
+     false, the release element is ignored.
+-->
+<!ELEMENT release    EMPTY>
+<!ATTLIST release
+          block      CDATA    #IMPLIED
+          if         CDATA    "1"
+>
+
 <!--================= The Signal Handler Element =================== -->
 <!--
      The signalhandler element defines how to handle a specified signal.
@@ -1122,6 +1061,119 @@
           signal     CDATA        #REQUIRED
 >
 
+<!--================= The Rethrow Element ========================= -->
+<!--
+     The rethrow element specifies to rethrow the current exception.
+-->
+<!ELEMENT rethrow      EMPTY>
+
+<!--================= The Block Element ============================ -->
+<!--
+     Defines a task block that can be held, released, or terminated.
+     Used in conjunction with the hold/terminate/release elements to
+     define a task block that can be held, terminated, or released.
+     The name attribute value is evaluated via Python.
+-->
+<!ELEMENT block      (%task;)>
+<!ATTLIST block
+          name       CDATA    #REQUIRED
+>
+
+<!--================= The Hold Element ============================= -->
+<!--
+     The hold element specifies to hold a block in the job.
+     If an if attribute is specified and it evaluates via Python to
+     false, the hold element is ignored.
+-->
+<!ELEMENT hold       EMPTY>
+<!ATTLIST hold
+          block      CDATA    #IMPLIED
+          if         CDATA    "1"
+>
+
+<!--================= The Terminate Element ======================== -->
+<!--
+     The terminate element specifies to terminate a block in the job.
+     If an if attribute is specified and it evaluates via Python to
+     false, the terminate element is ignored.
+-->
+<!ELEMENT terminate  EMPTY>
+<!ATTLIST terminate
+          block      CDATA    #IMPLIED
+          if         CDATA    "1"
+>
+
+<!--================= The Return Element =========================== -->
+<!--
+     Specifies a value to return from a function.
+-->
+<!ELEMENT return     (#PCDATA)>
+
+<!--================= The Conditional Element (if-then-else) ======= -->
+<!--
+     Allows you to write an if or a case construct with zero or more
+     elseifs and one or no else statements.
+
+     The expr attribute value is evaluated via Python and must evaluate
+     to a boolean value.
+-->
+<!ELEMENT if         ((%task;), elseif*, else?)>
+<!ATTLIST if
+          expr       CDATA   #REQUIRED
+>
+<!ELEMENT elseif     (%task;)>
+<!ATTLIST elseif
+          expr       CDATA   #REQUIRED
+>
+<!ELEMENT else       (%task;)>
+
+<!--================= The Call-With-List Element =================== -->
+<!--
+     Perform a function with the referenced name with any number of
+     arguments in the form of a list.  The function attribute value
+     and argument values are evaluated via Python.
+-->
+<!ELEMENT call-with-list      (call-list-arg*)>
+<!ATTLIST call-with-list
+          function   CDATA    #REQUIRED
+>
+
+<!ELEMENT call-list-arg       (#PCDATA)>
+
+
+<!--================= The Loop Element ============================= -->
+<!--
+     The loop element performs a task a specified number of times,
+     allowing specification of an upper and lower bound with an
+     increment value and where the index counter is available to
+     sub-tasks.  Also, while and/or until expressions can be
+     specified.
+-->
+<!ELEMENT loop       (%task;)>
+<!-- var      is the name of a variable which will contain the loop
+              index variable.  It is a literal.
+     from     is the starting value of the loop index variable.
+              It must evaluate to an integer value via Python.
+     to       is the maximum value of the loop index variable
+              It must evaluate to an integer value via Python.
+     by       is the increment value for the loop index variable
+              It must evaluate to an integer value via Python.
+     while    is an expression that must evaluate to a boolean value
+              and is performed at the top of each loop.  If it
+              evaluates to false, it breaks out of the loop.
+     until    is an expression that must evaluate to a boolean value
+              and is performed at the bottom of each loop.  If it
+              evaluates to false, it breaks out of the loop.
+-->
+<!ATTLIST loop
+          var        CDATA    #IMPLIED
+          from       CDATA    '1'
+          to         CDATA    #IMPLIED
+          by         CDATA    '1'
+          while      CDATA    #IMPLIED
+          until      CDATA    #IMPLIED
+>
+
 <!--================= The Call-With-Map Element ==================== -->
 <!--
      Perform a function with the referenced name with any number of
@@ -1139,52 +1191,3 @@
           name       CDATA    #REQUIRED
 >
 
-<!--================= The Sequence Element ========================= -->
-<!--
-     The sequence element performs one or more tasks in sequence.
--->
-<!ELEMENT sequence   (%task;)+>
-
-<!--================= Continue Element ============================= -->
-<!--
-     The continue element can be used to continue to the top of a loop
-     or iterate element.
--->
-<!ELEMENT continue   EMPTY>
-
-<!--================= The Release Element ========================== -->
-<!--
-     The release element specifies to release a block in the job.
-     If an if attribute is specified and it evaluates via Python to
-     false, the release element is ignored.
--->
-<!ELEMENT release    EMPTY>
-<!ATTLIST release
-          block      CDATA    #IMPLIED
-          if         CDATA    "1"
->
-
-<!--=============== The Try / Catch / Finally Elements ============= --> 
-<!-- 
-     The try element allows you to perform a task and to catch 
-     exceptions that are thrown.  Also, if a finally element is 
-     specified, then the finally task is executed, no matter whether 
-     the try task completes normally or abruptly, and no matter whether 
-     a catch element is first given control. 
---> 
-<!ELEMENT try        ((%task;), ((catch+) | ((catch*), finally)))> 
-<!-- 
-     The catch element performs a task when the specified exception is 
-     caught.  The var attribute specifies the name of the variable to 
-     receive the data specified within the throw element.  The typevar 
-     attribute specifies the name of the variable to receive the type 
-     of the exception. 
- 
---> 
-<!ELEMENT catch      (%task;)> 
-<!ATTLIST catch 
-          exception  CDATA        #REQUIRED 
-          var        CDATA        #IMPLIED 
-          typevar    CDATA        #IMPLIED 
-> 
-<!ELEMENT finally    (%task;)> 
diff --git a/opendj-sdk/opends/tests/staf-tests/shared/tests/config.py.stubs b/opendj-sdk/opends/tests/staf-tests/shared/tests/config.py.stubs
index f768bde..47b27d4 100644
--- a/opendj-sdk/opends/tests/staf-tests/shared/tests/config.py.stubs
+++ b/opendj-sdk/opends/tests/staf-tests/shared/tests/config.py.stubs
@@ -28,7 +28,7 @@
 STAF_LOCAL_HOSTNAME           = '${local.hostname}'
 STAF_REMOTE_HOSTNAME          = '${remote.hostname}'
 STAF_CLIENT_HOSTNAME          = '${client.hostname}'
-TMPDIR                        = '/tmp'
+TMPDIR                        = '${temp.dir}'
 OPENDSNAME                    = '${opends.name}'
 ZIPNAME                       = '${opends.name}.zip'
 ZIPPATH                       = '${opends.dir}'
@@ -40,6 +40,7 @@
 TESTS_JAVA_DIR                = '${shared.dir}/java'
 TESTS_TOPOLOGY_DIR            = '${shared.dir}/topology'
 TESTS_XSL_DIR                 = '${shared.dir}/xsl'
+TESTS_DSML_DIR                = '${shared.dir}/dsml'
 TESTS_RESOURCE_DIR            = '${shared.dir}/resource'
 DIRECTORY_INSTANCE_DN         = '${opends.admin.dn}'
 DIRECTORY_INSTANCE_PSWD       = '${opends.admin.pwd}'

--
Gitblit v1.10.0