Paul Lisewski 4 жил өмнө
commit
5e5df83eb9
34 өөрчлөгдсөн 9162 нэмэгдсэн , 0 устгасан
  1. 76 0
      build.xml
  2. 1420 0
      nbproject/build-impl.xml
  3. 8 0
      nbproject/genfiles.properties
  4. 121 0
      nbproject/project.properties
  5. 16 0
      nbproject/project.xml
  6. 82 0
      src/com/cloudsoft/utils/Base64.java
  7. 113 0
      src/com/cloudsoft/utils/Chart.java
  8. 103 0
      src/com/cloudsoft/utils/ChartHelper.java
  9. 1496 0
      src/com/cloudsoft/utils/DBHelper.java
  10. 222 0
      src/com/cloudsoft/utils/DBParams.java
  11. 357 0
      src/com/cloudsoft/utils/DeepZoom.java
  12. 83 0
      src/com/cloudsoft/utils/EncryptedProperties.java
  13. 514 0
      src/com/cloudsoft/utils/ErrHelper.java
  14. 53 0
      src/com/cloudsoft/utils/ExampleHttpSuper.java
  15. 58 0
      src/com/cloudsoft/utils/JARResourceResolver.java
  16. 50 0
      src/com/cloudsoft/utils/JARURIResolver.java
  17. 118 0
      src/com/cloudsoft/utils/LUHelper.java
  18. 70 0
      src/com/cloudsoft/utils/Log.java
  19. 17 0
      src/com/cloudsoft/utils/LogStats.java
  20. 173 0
      src/com/cloudsoft/utils/MailHelper.java
  21. 234 0
      src/com/cloudsoft/utils/MortonList.java
  22. 153 0
      src/com/cloudsoft/utils/Pictures.java
  23. 124 0
      src/com/cloudsoft/utils/PropertiesTask.java
  24. 109 0
      src/com/cloudsoft/utils/RegHelper.java
  25. 132 0
      src/com/cloudsoft/utils/ResourceList.java
  26. 92 0
      src/com/cloudsoft/utils/SAXLoadHandler.java
  27. 17 0
      src/com/cloudsoft/utils/SAXLoadInterface.java
  28. 331 0
      src/com/cloudsoft/utils/SCPHelper.java
  29. 135 0
      src/com/cloudsoft/utils/ScopeBase.java
  30. 99 0
      src/com/cloudsoft/utils/SimpleMail.java
  31. 744 0
      src/com/cloudsoft/utils/UIHelper.java
  32. 240 0
      src/com/cloudsoft/utils/WebProxy.java
  33. 1471 0
      src/com/cloudsoft/utils/XMLHelper.java
  34. 131 0
      src/xsl/scopeschema.xsl

+ 76 - 0
build.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="com.cloudsoft.utils" default="default" basedir=".">
+    <description>Builds, tests, and runs the project com.cloudsoft.utils.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="com.cloudsoft.utils-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+    <target name="-post-jar">
+        <copy file="${dist.jar}" tofile="../jLib/${ant.project.name}.jar"/>
+    </target>
+</project>

+ 1420 - 0
nbproject/build-impl.xml

@@ -0,0 +1,1420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+  - initialization
+  - compilation
+  - jar
+  - execution
+  - debugging
+  - javadoc
+  - test compilation
+  - test execution
+  - test debugging
+  - applet
+  - cleanup
+
+        -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="com.cloudsoft.utils-impl">
+    <fail message="Please build using Ant 1.8.0 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.8.0"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+    <!-- 
+                ======================
+                INITIALIZATION SECTION 
+                ======================
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/config.properties"/>
+        <property file="nbproject/private/configs/${config}.properties"/>
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.6"/>
+        <property name="default.javac.target" value="1.6"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/configs/${config}.properties"/>
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <property name="platform.java" value="${java.home}/bin/java"/>
+        <available file="${manifest.file}" property="manifest.available"/>
+        <condition property="splashscreen.available">
+            <and>
+                <not>
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>
+                </not>
+                <available file="${application.splash}"/>
+            </and>
+        </condition>
+        <condition property="main.class.available">
+            <and>
+                <isset property="main.class"/>
+                <not>
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="profile.available">
+            <and>
+                <isset property="javac.profile"/>
+                <length length="0" string="${javac.profile}" when="greater"/>
+                <matches pattern="((1\.[89])|9)(\..*)?" string="${javac.source}"/>
+            </and>
+        </condition>
+        <condition property="do.archive">
+            <or>
+                <not>
+                    <istrue value="${jar.archive.disabled}"/>
+                </not>
+                <istrue value="${not.archive.disabled}"/>
+            </or>
+        </condition>
+        <condition property="do.mkdist">
+            <and>
+                <isset property="do.archive"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <not>
+                    <istrue value="${mkdist.disabled}"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.archive+manifest.available">
+            <and>
+                <isset property="manifest.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+main.class.available">
+            <and>
+                <isset property="main.class.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+splashscreen.available">
+            <and>
+                <isset property="splashscreen.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+profile.available">
+            <and>
+                <isset property="profile.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="have.tests">
+            <or>
+                <available file="${test.src.dir}"/>
+            </or>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <and>
+                <isset property="javadoc.preview"/>
+                <isfalse value="${javadoc.preview}"/>
+            </and>
+        </condition>
+        <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
+        <property name="javac.compilerargs" value=""/>
+        <property name="work.dir" value="${basedir}"/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <property name="javac.debug" value="true"/>
+        <property name="javadoc.preview" value="true"/>
+        <property name="application.args" value=""/>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <property name="runtime.encoding" value="${source.encoding}"/>
+        <property name="manifest.encoding" value="${source.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="do.depend" value="false"/>
+        <condition property="do.depend.true">
+            <istrue value="${do.depend}"/>
+        </condition>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <not>
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+            <isset property="profile.available"/>
+        </condition>
+        <condition else="false" property="jdkBug6558476">
+            <and>
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>
+                <not>
+                    <os family="unix"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="javac.fork">
+            <or>
+                <istrue value="${jdkBug6558476}"/>
+                <istrue value="${javac.external.vm}"/>
+            </or>
+        </condition>
+        <property name="jar.index" value="false"/>
+        <property name="jar.index.metainf" value="${jar.index}"/>
+        <property name="copylibs.rebase" value="true"/>
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <property name="java.failonerror" value="true"/>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="test.src.dir">Must set test.src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.jar">Must set dist.jar</fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete>
+                    <fileset file="${javac.includesfile.binary}"/>
+                </delete>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set">
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
+                        <filename name="@{testincludes}"/>
+                    </fileset>
+                </union>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="com.cloudsoft.utils" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename com.cloudsoft.utils -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customize>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+        <macrodef name="resolve">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${env.@{value}}"/>
+            </sequential>
+        </macrodef>
+        <macrodef name="profile">
+            <attribute default="${main.class}" name="classname"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property environment="env"/>
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+                <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                    <jvmarg line="${profiler.info.jvmargs}"/>
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                    <arg line="${application.args}"/>
+                    <classpath>
+                        <path path="${run.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <attribute default="" name="stopclassname"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-copylibs">
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${manifest.file}" name="manifest"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+                <pathconvert property="run.classpath.without.build.classes.dir">
+                    <path path="${run.classpath}"/>
+                    <map from="${build.classes.dir.resolved}" to=""/>
+                </pathconvert>
+                <pathconvert pathsep=" " property="jar.classpath">
+                    <path path="${run.classpath.without.build.classes.dir}"/>
+                    <chainedmapper>
+                        <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
+                        <globmapper from="*" to="lib/*"/>
+                    </chainedmapper>
+                </pathconvert>
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" manifestencoding="UTF-8" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+                    <manifest>
+                        <attribute name="Class-Path" value="${jar.classpath}"/>
+                        <customize/>
+                    </manifest>
+                </copylibs>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-presetdef-jar">
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifestencoding="UTF-8">
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+            </jar>
+        </presetdef>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.processor.options" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <!--
+                ===================
+                COMPILATION SECTION
+                ===================
+            -->
+    <target name="-deps-jar-init" unless="built-jar.properties">
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+        <delete file="${built-jar.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+        <echo level="warn" message="Cycle detected: com.cloudsoft.utils was already built"/>
+    </target>
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-jar.properties}" verbose="false"/>
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>
+        <antcall target="-warn-already-built-jar"/>
+        <propertyfile file="${built-jar.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+    <target depends="init" name="-check-automatic-build">
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+    </target>
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+        <antcall target="clean"/>
+    </target>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-depend">
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy todir="${build.classes.dir}/META-INF">
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <!--
+                ====================
+                JAR BUILDING SECTION
+                ====================
+            -->
+    <target depends="init" name="-pre-pre-jar">
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+    </target>
+    <target name="-pre-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <touch file="${tmp.manifest.file}" verbose="false"/>
+    </target>
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <copy encoding="${manifest.encoding}" file="${manifest.file}" outputencoding="UTF-8" tofile="${tmp.manifest.file}"/>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Main-Class" value="${main.class}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Profile" value="${javac.profile}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+        <basename file="${application.splash}" property="splashscreen.basename"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+        </manifest>
+    </target>
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+        <echo level="info">To run this application from the command line without Ant, try:</echo>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <pathconvert property="run.classpath.with.dist.jar">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+        </pathconvert>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+            <isset property="main.class.available"/>
+        </condition>
+        <condition else="debug" property="jar.usage.level" value="info">
+            <isset property="main.class.available"/>
+        </condition>
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+    </target>
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+        <delete>
+            <fileset file="${tmp.manifest.file}"/>
+        </delete>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+    <target name="-post-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                EXECUTION SECTION
+                =================
+            -->
+    <target depends="init,compile" description="Run a main class." name="run">
+        <j2seproject1:java>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <target name="-do-not-recompile">
+        <property name="javac.includes.binary" value=""/>
+    </target>
+    <target depends="init,compile-single" name="run-single">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <!--
+                =================
+                DEBUGGING SECTION
+                =================
+            -->
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init,compile" name="-debug-start-debuggee">
+        <j2seproject3:debug>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+    </target>
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <j2seproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+                =================
+                PROFILING SECTION
+                =================
+            -->
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile/>
+    </target>
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="${profile.class}"/>
+    </target>
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </profile>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
+                ===============
+                JAVADOC SECTION
+                ===============
+            -->
+    <target depends="init" if="have.sources" name="-javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+            <and>
+                <isset property="endorsed.classpath.cmd.line.arg"/>
+                <not>
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="bug5101868workaround" value="*.java">
+            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
+        </condition>
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+                <exclude name="*.java"/>
+            </fileset>
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                =========================
+                TEST COMPILATION SECTION
+                =========================
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-test-depend">
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                =======================
+                TEST EXECUTION SECTION
+                =======================
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                =======================
+                TEST DEBUGGING SECTION
+                =======================
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                =========================
+                APPLET EXECUTION SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" name="run-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject1:java classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <!--
+                =========================
+                APPLET DEBUGGING  SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+    <!--
+                ===============
+                CLEANUP SECTION
+                ===============
+            -->
+    <target name="-deps-clean-init" unless="built-clean.properties">
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+        <delete file="${built-clean.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+        <echo level="warn" message="Cycle detected: com.cloudsoft.utils was already built"/>
+    </target>
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-clean.properties}" verbose="false"/>
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>
+        <antcall target="-warn-already-built-clean"/>
+        <propertyfile file="${built-clean.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init" name="-do-clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target name="-check-call-dep">
+        <property file="${call.built.properties}" prefix="already.built."/>
+        <condition property="should.call.dep">
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+            <propertyset>
+                <propertyref prefix="transfer."/>
+                <mapper from="transfer.*" to="*" type="glob"/>
+            </propertyset>
+        </ant>
+    </target>
+</project>

+ 8 - 0
nbproject/genfiles.properties

@@ -0,0 +1,8 @@
+build.xml.data.CRC32=746c945b
+build.xml.script.CRC32=a44e0e15
+build.xml.stylesheet.CRC32=28e38971@1.53.1.46
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=746c945b
+nbproject/build-impl.xml.script.CRC32=235f1a06
+nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

+ 121 - 0
nbproject/project.properties

@@ -0,0 +1,121 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+application.title=com.cloudsoft.utils
+application.vendor=paul
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/com.cloudsoft.utils.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.ant.jar=../jLib/ant.jar
+file.reference.avalon-framework-api-4.3.1.jar=../jLib/avalon-framework-api-4.3.1.jar
+file.reference.avalon-framework-impl-4.3.1.jar=../jLib/avalon-framework-impl-4.3.1.jar
+file.reference.batik-all-1.8.jar=../jLib/batik-all-1.8.jar
+file.reference.commons-io-1.3.1.jar=../jLib/commons-io-1.3.1.jar
+file.reference.commons-logging-1.0.4.jar=../jLib/commons-logging-1.0.4.jar
+file.reference.fontbox-1.8.5.jar=../jLib/fontbox-1.8.5.jar
+file.reference.fop.jar=../jLib/fop.jar
+file.reference.gson-2.2.4.jar=../jLib/gson-2.2.4.jar
+file.reference.javax.mail.jar=../jLib/javax.mail.jar
+file.reference.jcommon-1.0.16.jar=../jLib/jcommon-1.0.16.jar
+file.reference.jfreechart-1.0.13.jar=../jLib/jfreechart-1.0.13.jar
+file.reference.jsch-0.1.51.jar=../jLib/jsch-0.1.51.jar
+file.reference.ojdbc5.jar=../jLib/ojdbc5.jar
+file.reference.org.json.jar=../jLib/org.json.jar
+file.reference.serializer-2.7.0.jar=../jLib/serializer-2.7.0.jar
+file.reference.xml-apis-1.3.04.jar=../jLib/xml-apis-1.3.04.jar
+file.reference.xml-apis-ext-1.3.04.jar=../jLib/xml-apis-ext-1.3.04.jar
+file.reference.xmlgraphics-commons-2.1.jar=../jLib/xmlgraphics-commons-2.1.jar
+includes=**
+jar.archive.disabled=${jnlp.enabled}
+jar.compress=false
+jar.index=${jnlp.enabled}
+javac.classpath=\
+    ${file.reference.commons-logging-1.0.4.jar}:\
+    ${file.reference.gson-2.2.4.jar}:\
+    ${file.reference.jcommon-1.0.16.jar}:\
+    ${file.reference.jfreechart-1.0.13.jar}:\
+    ${file.reference.jsch-0.1.51.jar}:\
+    ${file.reference.fop.jar}:\
+    ${file.reference.ojdbc5.jar}:\
+    ${file.reference.org.json.jar}:\
+    ${file.reference.serializer-2.7.0.jar}:\
+    ${file.reference.xml-apis-1.3.04.jar}:\
+    ${file.reference.xml-apis-ext-1.3.04.jar}:\
+    ${libs.javaee-api-6.0.classpath}:\
+    ${file.reference.ant.jar}:\
+    ${file.reference.avalon-framework-api-4.3.1.jar}:\
+    ${file.reference.avalon-framework-impl-4.3.1.jar}:\
+    ${file.reference.batik-all-1.8.jar}:\
+    ${file.reference.commons-io-1.3.1.jar}:\
+    ${file.reference.fontbox-1.8.5.jar}:\
+    ${file.reference.javax.mail.jar}:\
+    ${file.reference.xmlgraphics-commons-2.1.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.external.vm=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
+jnlp.codebase.type=no.codebase
+jnlp.descriptor=application
+jnlp.enabled=false
+jnlp.mixed.code=default
+jnlp.offline-allowed=false
+jnlp.signed=false
+jnlp.signing=
+jnlp.signing.alias=
+jnlp.signing.keystore=
+main.class=com.cloudsoft.utils.Chart
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test

+ 16 - 0
nbproject/project.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <name>com.cloudsoft.utils</name>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots>
+                <root id="test.src.dir"/>
+            </test-roots>
+        </data>
+        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1"/>
+    </configuration>
+</project>

+ 82 - 0
src/com/cloudsoft/utils/Base64.java

@@ -0,0 +1,82 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author paul
+ */
+public class Base64 
+{
+
+    private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
+
+    private static int[]  toInt   = new int[128];
+
+    static {
+        for(int i=0; i< ALPHABET.length; i++){
+            toInt[ALPHABET[i]]= i;
+        }
+    }
+
+    /**
+     * Translates the specified byte array into Base64 string.
+     *
+     * @param buf the byte array (not null)
+     * @return the translated Base64 string (not null)
+     */
+    public static String encode(byte[] buf){
+        int size = buf.length;
+        char[] ar = new char[((size + 2) / 3) * 4];
+        int a = 0;
+        int i=0;
+        while(i < size){
+            byte b0 = buf[i++];
+            byte b1 = (i < size) ? buf[i++] : 0;
+            byte b2 = (i < size) ? buf[i++] : 0;
+
+            int mask = 0x3F;
+            ar[a++] = ALPHABET[(b0 >> 2) & mask];
+            ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
+            ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
+            ar[a++] = ALPHABET[b2 & mask];
+        }
+        switch(size % 3){
+            case 1: ar[--a]  = '=';
+            case 2: ar[--a]  = '=';
+        }
+        return new String(ar);
+    }
+
+    /**
+     * Translates the specified Base64 string into a byte array.
+     *
+     * @param s the Base64 string (not null)
+     * @return the byte array (not null)
+     */
+    public static byte[] decode(String s){
+        int delta = s.endsWith( "==" ) ? 2 : s.endsWith( "=" ) ? 1 : 0;
+        byte[] buffer = new byte[s.length()*3/4 - delta];
+        int mask = 0xFF;
+        int index = 0;
+        for(int i=0; i< s.length(); i+=4){
+            int c0 = toInt[s.charAt( i )];
+            int c1 = toInt[s.charAt( i + 1)];
+            buffer[index++]= (byte)(((c0 << 2) | (c1 >> 4)) & mask);
+            if(index >= buffer.length){
+                return buffer;
+            }
+            int c2 = toInt[s.charAt( i + 2)];
+            buffer[index++]= (byte)(((c1 << 4) | (c2 >> 2)) & mask);
+            if(index >= buffer.length){
+                return buffer;
+            }
+            int c3 = toInt[s.charAt( i + 3 )];
+            buffer[index++]= (byte)(((c2 << 6) | c3) & mask);
+        }
+        return buffer;
+    } 
+
+}

+ 113 - 0
src/com/cloudsoft/utils/Chart.java

@@ -0,0 +1,113 @@
+/*
+ * Chart.java
+ *
+ * Created on 04 August 2006, 11:14
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+
+// Import the Swing classes
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+// Import the JFreeChart classes
+import org.jfree.chart.*;
+import org.jfree.chart.plot.*;
+import org.jfree.data.*;
+import org.jfree.data.general.*;
+
+/**
+ *
+ * @author pyl38997
+ */
+public class Chart extends JPanel
+{
+  // Holds the data
+  private DefaultPieDataset dataset = new DefaultPieDataset();
+
+  // Create a set of charts
+  private JFreeChart chart1;
+  private JFreeChart chart2;
+  private JFreeChart chart3;
+  private JFreeChart chart4;
+
+  // Create a set of panels that can show charts
+  private ChartPanel panel1;
+  private ChartPanel panel2;
+  private ChartPanel panel3;
+  private ChartPanel panel4;
+    
+    /** Creates a new instance of Chart */
+    public Chart()
+    {
+    // Initialize the dataset
+    dataset.setValue( "California", new Double( 10.0 ) );
+    dataset.setValue( "Arizona", new Double( 8.0 ) );
+    dataset.setValue( "New Mexico", new Double( 8.0 ) );
+    dataset.setValue( "Texas", new Double( 40.0 ) );
+    dataset.setValue( "Louisiana", new Double( 8.0 ) );
+    dataset.setValue( "Mississippi", new Double( 4.0 ) );
+    dataset.setValue( "Alabama", new Double( 2.0 ) );
+    dataset.setValue( "Florida", new Double( 20.0 ) );
+
+    // Create the charts
+    chart1 = ChartFactory.createPieChart(
+      "Driving Time Spent Per State (Flat Pie Chart)", // The chart title
+      dataset,         // The dataset for the chart
+      true,          // Is a legend required?
+      true,          // Use tooltips
+      false          // Configure chart to generate URLs?
+    );
+    chart2 = ChartFactory.createPieChart(
+      "Driving Time Spent Per State (Exploded Pie Chart)", // The chart title
+      dataset,         // The dataset for the chart
+      true,          // Is a legend required?
+      true,          // Use tooltips
+      false          // Configure chart to generate URLs?
+    );
+    PiePlot plot = ( PiePlot )chart2.getPlot();
+    plot.setExplodePercent( "Texas", 0.25 );
+
+    chart3 = ChartFactory.createPieChart3D(
+      "Driving Time Spent Per State (3D Pie Chart)", // The chart title
+      dataset,         // The dataset for the chart
+      true,          // Is a legend required?
+      true,          // Use tooltips
+      false          // Configure chart to generate URLs?
+    );
+    chart4 = ChartFactory.createPieChart3D(
+      "Driving Time Spent Per State (3D with Transparency)", // The chart title
+      dataset,         // The dataset for the chart
+      true,          // Is a legend required?
+      true,          // Use tooltips
+      false          // Configure chart to generate URLs?
+    );
+    PiePlot3D plot4 = ( PiePlot3D )chart4.getPlot();
+    plot4.setForegroundAlpha( 0.6f );
+
+    // Create this panel
+    this.setLayout( new GridLayout( 2, 2 ) );
+    this.panel1 = new ChartPanel( chart1 );
+    this.panel2 = new ChartPanel( chart2 );
+    this.panel3 = new ChartPanel( chart3 );
+    this.panel4 = new ChartPanel( chart4 );
+    this.add( panel1 );
+    this.add( panel2 );
+    this.add( panel3 );
+    this.add( panel4 );
+  }
+
+  public static void main( String[] args )
+  {
+    JFrame frame = new JFrame( "My Trip Driving From CA to FL..." );
+    Chart chart = new Chart();
+    frame.getContentPane().add( chart, BorderLayout.CENTER );
+    frame.setSize( 640, 480 );
+    frame.setVisible( true );
+    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
+  }
+} 

+ 103 - 0
src/com/cloudsoft/utils/ChartHelper.java

@@ -0,0 +1,103 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.InputStream;
+import java.io.Writer;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author a-palise
+ */
+public class ChartHelper {
+    public void getSVG(String options, Writer out) {
+        try {
+            URL url = new URL("http://localhost:8080/highcharts-export-web/");
+            Map<String,Object> params = new LinkedHashMap<>();
+//            String options = "{ " +
+//                "	xAxis: { " +
+//                "		categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', " +
+//                "			'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] " +
+//                "	}, " +
+//                "	series: [{ " +
+//                "		data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, " +
+//                "			135.6, 148.5, 216.4, 194.1, 95.6, 54.4] " +
+//                "	}] " +
+//                "}";
+            
+            
+            params.put("type", "image/svg+xml");
+    //        params.put("content", "options");
+            params.put("options", options);
+//            {lang: {thousandsSep: ','})
+            params.put("globaloptions", "{lang: {thousandsSep: ','}}");
+            params.put("scale", "4");
+    //        params.put("async", "true");
+    //        params.put("constr", "Chart");
+
+            StringBuilder postData = new StringBuilder();
+            for (Map.Entry<String,Object> param : params.entrySet()) {
+                if (postData.length() != 0) postData.append('&');
+                postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
+                postData.append('=');
+                postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
+            }
+            byte[] postDataBytes = postData.toString().getBytes("UTF-8");
+
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+            conn.setRequestMethod("POST");
+            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
+            conn.setDoOutput(true);
+            conn.getOutputStream().write(postDataBytes);
+
+            InputStream in = conn.getInputStream();
+            for ( int c = in.read(); c != -1; c = in.read() )
+                out.write((char)c);
+        }  catch (Exception ex) {
+            
+        }
+        
+    }
+    public void getPNG(String options, Writer out) {
+        try {
+            URL url = new URL("http://localhost:8080/highcharts-export-web/");
+            Map<String,Object> params = new LinkedHashMap<>();
+            params.put("type", "image/png");
+            params.put("options", options);
+            params.put("scale", "4");
+
+            StringBuilder postData = new StringBuilder();
+            for (Map.Entry<String,Object> param : params.entrySet()) {
+                if (postData.length() != 0) postData.append('&');
+                postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
+                postData.append('=');
+                postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
+            }
+            byte[] postDataBytes = postData.toString().getBytes("UTF-8");
+
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+            conn.setRequestMethod("POST");
+            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
+            conn.setDoOutput(true);
+            conn.getOutputStream().write(postDataBytes);
+
+            InputStream in = conn.getInputStream();
+            for ( int c = in.read(); c != -1; c = in.read() )
+                out.write((char)c);
+        }  catch (Exception ex) {
+            
+        }
+        
+    }
+    
+}

+ 1496 - 0
src/com/cloudsoft/utils/DBHelper.java

@@ -0,0 +1,1496 @@
+/*
+ * DBHelper.java
+ *
+ * Created on June 26, 2003, 10:45 PM
+ */
+package com.cloudsoft.utils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ *
+ * @author paull
+ */
+public class DBHelper extends ErrHelper {
+
+    boolean lbUpperCaseNodes = false;
+    boolean lbIsSQLServer = false;
+    boolean lbIsOracle = false;
+    boolean lbIsMysql = false;
+    boolean lbIsPostgres = false;
+    boolean lbAutoCommit = true;
+    String lzDateFormat = "yyyy-MM-dd";
+    protected Connection oConnection = null;
+    XMLHelper _request = null;
+    DBParams _command = null;
+    ArrayList<String> _aParser = new ArrayList<>();
+
+    /**
+     * Creates a new instance of DBHelper
+     */
+    public DBHelper() {
+        this("jdbc");
+    }
+
+    public DBHelper(String zSystem) {
+        this(zSystem, true);
+    }
+
+    public DBHelper(String zSystem, boolean bAutocommit) {
+        this(zSystem, bAutocommit, null);
+    }
+
+    public DBHelper(String zSystem, boolean bAutocommit, String zDateFormat) {
+        zgSystem = zSystem;
+        lbAutoCommit = bAutocommit;
+        if (zDateFormat != null) {
+            lzDateFormat = zDateFormat;
+        }
+    }
+//    public DBHelper(String zSystem, boolean bUppercaseNodes, String zDateFormat) {
+//        zgSystem = zSystem;
+//        lbUpperCaseNodes = bUppercaseNodes;
+//        lzDateFormat = zDateFormat;
+//    }
+
+    public DBHelper(XMLHelper oRequest) {
+        this(oRequest, (oRequest._con == null));
+    }
+
+    public DBHelper(XMLHelper oRequest, boolean bAutocommit) {
+        this(oRequest, bAutocommit, null);
+    }
+    public DBHelper(XMLHelper oRequest, boolean bAutocommit, String zDateFormat) {
+        lbAutoCommit = bAutocommit;
+        _request = oRequest;
+        zgSystem = oRequest.getString("system");
+        oConnection = oRequest._con;
+        if (zDateFormat != null) {
+            lzDateFormat = zDateFormat;
+        }
+    }
+
+    public Clob getClob() throws Exception {
+        return oConnection.createClob();
+    }
+
+    public XMLHelper getDOM(DBParams oCommand) throws Exception {
+        return getDOM(oCommand, "rows", "row");
+    }
+
+    public XMLHelper getDOM(DBParams oCommand, String zRowsetName, String zRowName) throws Exception {
+        return getDOM(oCommand, zRowsetName, zRowName, false, false, 0, 9999999);
+    }
+
+    public XMLHelper getDOM(DBParams oCommand, String zRowsetName, String zRowName, boolean bShowMetadata, boolean bShowTotal, int iStartRow, int iMaxRows) throws Exception {
+        ResultSet oRS;
+        if (oCommand.hasCursor()) {
+            oCommand.Command.execute();
+            oRS = (ResultSet) oCommand.Command.getResultSet();
+        } else {
+            oRS = oCommand.Command.executeQuery();
+        }
+        //ResultSet oRS = (ResultSet) oCommand.Command.getObject(1);
+        return getDOM(oRS, iStartRow, iMaxRows, bShowTotal, zRowsetName, zRowName, bShowMetadata);
+    }
+
+    public XMLHelper getDOM(String zSQL) throws Exception {
+        return getDOM(zSQL, 0, 0, false, "rows", "row", false);
+    }
+
+    public XMLHelper getDOM(String zSQL, String zRowsetName, String zRowName) throws Exception {
+        return getDOM(zSQL, 0, 0, false, zRowsetName, zRowName, false);
+    }
+
+    public XMLHelper getDOM(String zSQL, int iStartRow, int iMaxRows, boolean bShowTotal, String zRowsetName, String zRowName, boolean bShowMetadata) throws Exception {
+        _command = createSPParams(zSQL);
+        return getDOM(_command, zRowsetName, zRowName, bShowMetadata, bShowTotal, iStartRow, iMaxRows);
+    }
+
+    public int writeXML(String zSQL, OutputStream out) throws Exception {
+//        if (!lbIsMysql) {
+//            setAutoCommit(false);
+//        }
+        int iRows = 0;
+        XMLOutputFactory xof = XMLOutputFactory.newInstance();
+        XMLStreamWriter xsw = xof.createXMLStreamWriter(out, "utf-8");
+        Statement stmt = getConnection().createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
+        stmt.setFetchSize(lbIsMysql ? Integer.MIN_VALUE : 100);
+//        stmt.setFetchSize(Integer.MIN_VALUE);
+//        stmt.execute(zSQL);
+//        ResultSet oRS = stmt.getResultSet();
+        ResultSet oRS = stmt.executeQuery(zSQL);
+//        _command = createSPParams(zSQL);
+//        ResultSet oRS = _command.Command.executeQuery();
+         
+        xsw.writeStartDocument("utf-8", "1.0");
+        xsw.writeStartElement("response");
+
+        //Metadata
+        ResultSetMetaData rm = oRS.getMetaData();
+        xsw.writeStartElement("meta_data");
+        xsw.writeStartElement("columns");
+        for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+            xsw.writeStartElement("column");
+            xsw.writeAttribute("name", rm.getColumnName(i).toLowerCase());
+            xsw.writeAttribute("type", rm.getColumnTypeName(i).toLowerCase());
+            xsw.writeAttribute("sql_type", Integer.toString(rm.getColumnType(i)));
+            xsw.writeAttribute("length", Integer.toString(rm.getPrecision(i)));
+            xsw.writeAttribute("scale", Integer.toString(rm.getScale(i)));
+            xsw.writeEndElement();
+        }
+        xsw.writeEndElement(); //columns
+        xsw.writeEndElement(); //meta_data
+        String zNodeValue;
+        xsw.writeStartElement("rows");
+        //  Loop through the recordset and construct the XML DOM
+        while (oRS.next()) {
+            iRows++;
+//            if (iRows%500 == 0) {
+//                System.out.println(iRows);
+//            }
+            xsw.writeStartElement("row");
+            for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+
+                if (rm.getColumnType(i) == Types.TIMESTAMP) {
+                    SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat + " HH:mm:ss");
+                    try {
+                        zNodeValue = sdf.format(oRS.getTimestamp(i));
+                    } catch (Exception ex) {
+                        zNodeValue = "";
+                    }
+                } else if (rm.getColumnType(i) == Types.DATE) {
+                    SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat);
+                    try {
+                        zNodeValue = sdf.format(oRS.getDate(i));
+                    } catch (Exception ex) {
+                        zNodeValue = "";
+                    }
+                } else if (rm.getColumnType(i) == Types.CLOB) {
+                    // read the clob value
+                    Clob oClob = oRS.getClob(i);
+                    if (oClob == null) {
+                        zNodeValue = "";
+                    } else {
+                        // Buffer to hold the CLOB data
+                        StringBuilder clobData = new StringBuilder();
+                        // Open the stream to read data
+                        Reader oReader = oClob.getCharacterStream();
+                        char[] charbuffer = new char[255];
+
+                        // Keep reading from the CLOB and append it to the StringBuilder till
+                        // there is no more to read
+                        int bytesread;
+                        while ((bytesread = oReader.read(charbuffer)) != -1) {
+                            clobData.append(charbuffer, 0, bytesread);
+                        }
+                        zNodeValue = clobData.toString();
+                    }
+                } else {
+                    zNodeValue = oRS.getString(i);
+                }
+                String zNodeName = rm.getColumnLabel(i).toLowerCase().replaceAll("\"", "");
+                if (lbUpperCaseNodes) {
+                    zNodeName = zNodeName.toUpperCase();
+                }
+//                        if (i == 1)
+//                            oRow = oRows.appendNode(zRowName);
+
+//                if (zNodeName.endsWith("xml")) {
+//                    if (zNodeValue != null && zNodeValue.length() > 0) {
+//                        XMLHelper oXML = new XMLHelper();
+//                        oXML.load(zNodeValue);
+//                        xsw.writeStartElement(zNodeName);
+//                        xsw.writeCharacters(oXML.getXML());
+////                        OutputStreamWriter osw = new OutputStreamWriter(out);
+////                        // add a > remove last >
+////                        String zTemp = oXML.getXML();
+////                        zTemp  = ">" + zTemp.substring(0, zTemp.length()-1);
+////                        osw.write(zTemp);
+////                        osw.flush();
+//                        xsw.writeEndElement();
+//                    }
+//                } else {
+                    //  Add the field to the current row
+                    xsw.writeStartElement(zNodeName);
+                    xsw.writeCharacters(zNodeValue);
+                    xsw.writeEndElement();
+//                }
+            }
+            xsw.writeEndElement();
+            xsw.flush();
+            out.flush();
+        }
+//        if (lbAutoCommit == false) {
+//            commit();
+//        }
+        oRS.close();
+//        oRS.getStatement().close();
+        xsw.writeEndElement(); //rows
+        xsw.writeEndElement();
+        xsw.writeEndDocument();
+        xsw.flush();
+        xsw.close();
+        out.flush();
+        out.close();
+        return iRows;
+
+    }
+
+    public String parseSQL(String zSQL) throws Exception {
+        _aParser = new ArrayList<>();
+        return parseSQL(zSQL, false);
+    }
+
+    public String parseSQL(String zSQL, boolean bConditional) throws Exception {
+        try {
+            //Make sure square brackets are even
+            int iEven = 0;
+            for (int i = 0, n = zSQL.length(); i < n; i++) {
+                char c = zSQL.charAt(i);
+                if (c == '[') {
+                    iEven++;
+                }
+                if (c == ']') {
+                    iEven--;
+                }
+            }
+            if (iEven != 0) {
+                throwError("Square brackets must be matched", ErrorType.Information);
+            }
+
+            // Find optional clauses
+            Pattern regex = Pattern.compile("\\[([^\\[\\]]+|\\[([^\\[\\]]+|\\[([^\\[\\]]+)*\\])*\\])*\\]");
+            Matcher matcher = regex.matcher(zSQL);
+            int iCurr = 0;
+            StringBuilder sb = new StringBuilder();
+            while (matcher.find()) {
+                sb.append(replaceSQLVars(zSQL.substring(iCurr, matcher.start()), bConditional));
+                //iCurr = matcher.start() + matcher.end();
+                iCurr = matcher.end();
+                String match = matcher.group(0);
+                match = match.substring(1, match.length() - 1);
+                if (matcher.group(2) != null) {
+                    sb.append(parseSQL(match, true));
+                } else {
+                    sb.append(replaceSQLVars(match, true));
+                }
+            }
+
+            sb.append(replaceSQLVars(zSQL.substring(iCurr), false));
+            return sb.toString();
+        } catch (Exception ex) {
+            logError(ex);
+            return "";
+        }
+    }
+
+    private String replaceSQLVars(String zSQL, Boolean bConditional) throws Exception {
+        try {
+            // Find variables to replace
+            Pattern regex = Pattern.compile("[vilcbotdf]?:[:@a-zA-Z_0-9./]*");
+            Matcher matcher = regex.matcher(zSQL);
+            StringBuilder sb = new StringBuilder();
+            int iCurr = 0;
+            while (matcher.find()) {
+                // Get the replace value
+                String match = matcher.group(0);
+                String zMatch = match.substring(match.indexOf(':') + 1);
+                char zMatchType = match.charAt(0);
+
+                // If this is a conditional replace return nothing as soon as a variable is empty
+                //if (bConditional && _request.getString(zMatch) == "" && zMatchType != 'o')
+                if (bConditional && _request.getString(zMatch).equals("")) {
+                    return "";
+                }
+                String zTextBefore = zSQL.substring(iCurr, matcher.start());
+                String zReplace;
+                switch (zMatchType) {
+                    case ':':
+                        if (zMatch.equals(":")) {
+                            zReplace = ":";
+                            break;
+                        }
+                    case 'o':
+                        zReplace = _request.getString(zMatch);
+                        //if (zReplace == "") zReplace = "=";
+                        if (zReplace.equals("soundex")) {
+                            String[] arrWords = zTextBefore.split(" ");
+                            zReplace += "(" + arrWords[arrWords.length - 1] + ") = ";
+                            zTextBefore = "";
+                            for (int i = 0; i < arrWords.length - 1; i++) {
+                                zTextBefore += arrWords[i] + " ";
+                            }
+                        }
+                        break;
+                    case 'i':
+                    case 'f':
+                    case 't':
+                    case 'd':
+                    case 'b':
+                        zReplace = "?";
+                        _aParser.add(match);
+                        break;
+                    default:
+                        zReplace = "?";
+                        String zOp = _request.getString("op_" + zMatch);
+                        if (zOp.equals("soundex")) {
+                            zReplace = "soundex('" + zReplace + "')";
+                        } else if (zOp.equals("like")) {
+                            match = "l:" + zMatch;
+                        }
+                        _aParser.add(match);
+                        break;
+                }
+                sb.append(zTextBefore);
+                iCurr = matcher.end();
+                sb.append(zReplace);
+            }
+            sb.append(zSQL.substring(iCurr));
+            return sb.toString();
+        } catch (Exception ex) {
+            logError(ex);
+            return "";
+        }
+    }
+
+    private void addParserParams() throws Exception {
+        addParserParams(_request);
+    }
+
+    private void addParserParams(String zXPath) throws Exception {
+        for (XMLHelper oNode : _request.getNodes(zXPath)) {
+            addParserParams(oNode);
+            _command.addBatch();
+        }
+    }
+
+    private void addParserParams(XMLHelper oNode) throws Exception {
+
+        for (int i = 0; i < _aParser.size(); i++) {
+            // Get the replace value
+            String match = _aParser.get(i);
+            String zMatch = match.substring(match.indexOf(':') + 1);
+            char zMatchType = match.charAt(0);
+            Object oParam;
+            String zValue = (zMatch.equals("xml_data")) ? oNode.getNode(zMatch).getFirstChild().getXML() : oNode.getString(zMatch);
+            int iType = Types.VARCHAR;
+            switch (zMatchType) {
+                case 'f':
+                    oParam = oNode.getDouble(zMatch);
+                    iType = Types.DOUBLE;
+                    break;
+                case 'i':
+                    oParam = oNode.getInt(zMatch);
+                    iType = Types.BIGINT;
+                    break;
+                case 't':
+                    oParam = oNode.getSQLDateTime(zMatch);
+                    iType = Types.TIMESTAMP;
+                    break;
+                case 'd':
+                    oParam = oNode.getSQLDate(zMatch);
+                    iType = Types.DATE;
+                    break;
+                case 'b':
+                    oParam = oNode.get10(zMatch);
+                    iType = Types.INTEGER;
+                    break;
+                case 'c':
+                    oParam = zValue;
+                    iType = Types.CLOB;
+                    break;
+                case 'l':
+                    oParam = "%" + zValue + "%";
+                    zValue = (String) oParam;
+                    break;
+                default:
+                    oParam = zValue;
+            }
+            if (zValue.length() == 0) {
+                oParam = null;
+            }
+
+            _command.set(i + 1, oParam, iType);
+        }
+
+    }
+
+    public XMLHelper getDOM(ResultSet oRS) throws Exception {
+        return getDOM(oRS, 0, 99999, false, "rows", "row", false);
+    }
+
+    /**
+     * Takes a JDBC ResultSet to create an XML DOM of the resultset.
+     *
+     * @param iMaxRows
+     * @param bShowTotal
+     * @param zRowsetName
+     * @param zRowName
+     * @param bShowMetadata
+     * @param oRS The resultset to create the DOM from
+     * @param iStartRow The row to start at
+     * @return
+     * @throws Exception
+     */
+    public XMLHelper getDOM(ResultSet oRS, int iStartRow, int iMaxRows, boolean bShowTotal, String zRowsetName, String zRowName, boolean bShowMetadata) throws Exception {
+
+        /*    lMaxRows Optional. The maximum number of rows to return. Default 0 (All)
+         bShowTotal Optional. Determines whether the total Rowcount is shown. Default false
+         zRowsetName Optional. The Rowset node name. Default "Rows"
+         zRowName. Optional. The Row node name. Default "Row"
+         bHideMetaData. Optional. Determined whether to create meta data info. Default false
+         Outputs:       The resulting XML DOM as a string
+         **************************************************************************/
+//GetXMLDOM(ByVal rsRecordSet As Recordset, Optional ByVal lStartRow As Long = 0, Optional ByVal lMaxRows As Long = 0, Optional ByVal bShowTotal As Boolean = False, Optional ByVal zRowsetName As String = "rows", Optional ByVal zRowname As String = "row",
+//        Optional ByVal bShowMetadata As Boolean = False,
+//        Optional oInputDom As MSXML2.IXMLDOMNode = Nothing, Optional zNode As String = "", Optional zKey As String = "", Optional zGrouping As String = "") As MSXML2.DOMDocument40
+        try {
+            XMLHelper oResponse = new XMLHelper("response");
+            this.appendToDOM(oResponse, null, null, oRS, zRowsetName, zRowName, iStartRow, iMaxRows, bShowTotal, bShowMetadata);
+            return oResponse;
+        } catch (Exception e) {
+            handleError(e);
+            return (null);
+        }
+    }
+
+    public void appendToDOM(XMLHelper oInputDom, String zSQL, String zRowsetName, String zRowName) throws Exception {
+        ResultSet oRS = this.getRS(zSQL);
+        this.appendToDOM(oInputDom, null, null, oRS, zRowsetName, zRowName, 0, 9999999, false, false);
+    }
+
+    public void appendToDOM(String zSQL, String zRowsetName, String zRowName, XMLHelper oInputDom, String zNode, String zKey) throws Exception {
+        ResultSet oRS = this.getRS(zSQL);
+        appendToDOM(oInputDom, zNode, zKey, oRS, zRowsetName, zRowName, 0, 9999999, false, false);
+    }
+
+    public void appendToDOM(XMLHelper oInputDom, String zNode, String zKey, ResultSet oRS, String zRowsetName, String zRowName, int iStartRow, int iMaxRows, boolean bShowTotal, boolean bShowMetadata) {
+        XMLHelper oResponse = oInputDom;
+        XMLHelper oRows = oInputDom;
+        XMLHelper oRow = null;
+        String zNodeValue;
+        if (zNode == null) {
+            zNode = "";
+        }
+        if (zKey == null) {
+            zKey = "";
+        }
+        if (zRowsetName == null) {
+            zRowsetName = "";
+        }
+        if (zRowName == null) {
+            zRowName = "";
+        }
+        try {
+
+            ResultSetMetaData rm = oRS.getMetaData();
+
+            //  Include Metadata ?
+            if (bShowMetadata) {
+                XMLHelper oMeta = oResponse.appendNode("meta_data");
+                XMLHelper oCols = oMeta.appendNode("columns");
+                for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+                    XMLHelper oNode = oCols.appendNode("column");
+                    oNode.appendAttribute("name", rm.getColumnName(i).toLowerCase());
+                    oNode.appendAttribute("type", rm.getColumnTypeName(i).toLowerCase());
+                    oNode.appendAttribute("sql_type", Integer.toString(rm.getColumnType(i)));
+                    oNode.appendAttribute("length", Integer.toString(rm.getPrecision(i)));
+                    oNode.appendAttribute("scale", Integer.toString(rm.getScale(i)));
+                }
+            }
+
+            // Set the start row and max rows
+            int iRow = iStartRow;
+            if (iMaxRows == 0) {
+                iMaxRows = 100000;
+            }
+            if (iStartRow > 0) {
+                for (int i = 0; i < iStartRow; i++) {
+                    oRS.next();
+                }
+            }
+
+            //HashMap oKeys = new HashMap();
+            HashMap<String, XMLHelper> oKeys = new HashMap<>();
+            if (!zRowsetName.equals("") && zNode.equals("")) {
+                oRows = oResponse.appendNode(zRowsetName);
+            }
+
+            // Create a collection of keys in the DOM
+            if (!zNode.equals("")) {
+                XMLHelper aNodes[] = oResponse.getNodes(zNode);
+                for (XMLHelper aNode : aNodes) {
+                    oRows = aNode;
+                    if (!zRowsetName.equals("")) {
+                        oRows = oRows.appendNode(zRowsetName);
+                    }
+                    if (!zKey.equals("")) {
+                        oKeys.put(aNode.getValue(zKey), oRows);
+                    }
+                }
+            }
+
+            //  Loop through the recordset and construct the XML DOM
+            while (oRS.next() && iRow < (iMaxRows + iStartRow)) {
+                if (iRow >= iStartRow) {
+                    for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+                        if (rm.getColumnType(i) == Types.TIMESTAMP) {
+                            SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat + " HH:mm:ss");
+                            try {
+                                zNodeValue = sdf.format(oRS.getTimestamp(i));
+                            } catch (Exception ex) {
+                                zNodeValue = "";
+                            }
+                        } else if (rm.getColumnType(i) == Types.DATE) {
+                            SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat);
+                            try {
+                                zNodeValue = sdf.format(oRS.getDate(i));
+                            } catch (Exception ex) {
+                                zNodeValue = "";
+                            }
+                        } else if (rm.getColumnType(i) == Types.CLOB) {
+                            // read the clob value
+                            Clob oClob = oRS.getClob(i);
+                            if (oClob == null) {
+                                zNodeValue = "";
+                            } else {
+                                // Buffer to hold the CLOB data
+                                StringBuilder clobData = new StringBuilder();
+                                // Open the stream to read data
+                                Reader oReader = oClob.getCharacterStream();
+                                //  Buffer size is fixed using the getBufferSize() method which
+                                //  returns the optimal buffer size to read data from the LOB
+                                char[] charbuffer = new char[255];
+
+                                // Keep reading from the CLOB and append it to the StringBuilder till
+                                // there is no more to read
+                                int bytesread;
+                                while ((bytesread = oReader.read(charbuffer)) != -1) {
+                                    clobData.append(charbuffer, 0, bytesread);
+                                }
+                                zNodeValue = clobData.toString();
+                            }
+                        } else {
+                            zNodeValue = oRS.getString(i);
+                        }
+                        String zNodeName = rm.getColumnLabel(i).replaceAll("\"", "");
+                        if (lbIsOracle) {
+                            zNodeName = zNodeName.toLowerCase();
+                        }
+                        if (lbUpperCaseNodes) {
+                            zNodeName = zNodeName.toUpperCase();
+                        }
+                        if (i == 1 && !zKey.equals("")) {
+                            oRows = (XMLHelper) oKeys.get(zNodeValue);
+                            oRow = oRows.appendNode(zRowName);
+                        } else {
+                            if (i == 1) {
+                                oRow = oRows.appendNode(zRowName);
+                            }
+
+                            if (zNodeName.startsWith("xml")) {
+                                if (zNodeValue != null) {
+                                    XMLHelper oXML = new XMLHelper();
+                                    oXML.load(zNodeValue);
+                                    oRow.appendNode(zNodeName).appendNode(oXML);
+                                }
+                            } else {
+                                //  Add the field to the current row
+                                oRow.appendXPathNode(zNodeName, zNodeValue);
+                            }
+                        }
+                    }
+                    iRow++;
+                }
+            }
+            //  If total is to be shown move to the end of the recordset
+            if (bShowTotal) {
+                while (oRS.next() && iRow < iMaxRows) {
+                    iRow++;                //oAttrib = oResponse.createAttribute("total_rows");
+                    //oAttrib.setNodeValue(new String("") + iRow);
+                }
+                oRows.appendAttribute("total_rows", Integer.toString(iRow));
+            }
+            oRS.close();
+
+        } catch (SQLException ex) {
+            logError(ex);
+        } catch (IOException ex) {
+            logError(ex);
+        }
+    }
+
+    /*   public ResultSet getSPRS(String zSP)
+     {
+     Connection db;
+     try
+     {
+
+     // Setup the call.
+     CallableStatement toesUp
+     = connection.prepareCall("{ ? = call list_early_deaths () }");
+     toesUp.registerOutParameter(1, Types.OTHER);
+     getResults.execute();
+
+     ResultSet rs = (ResultSet) getResults.getObject(1);
+     return(rs);
+     }
+     catch(Exception e)
+     {
+     System.out.println(e.getMessage());
+     return(null);
+     }
+     }
+     */
+    public HashMap getTypes() {
+        //HashMap oTypes = new HashMap();
+        HashMap<Integer, String> oTypes = new HashMap<>();
+        try {
+            ResultSet rs = this.getMetaData().getTypeInfo();
+            while (rs.next()) {
+                String name = rs.getString(1);
+                Integer dt = rs.getInt(2);
+                if (name.equalsIgnoreCase("name") == false && oTypes.containsKey(dt) == false) {
+                    oTypes.put(dt, name);
+                }
+            }
+            rs.close();
+        } catch (Exception ex) {
+            logError(ex);
+        }
+
+        return (oTypes);
+    }
+
+    public XMLHelper getTables(String zSchema) {
+        return getTables(null, zSchema);
+    }
+    public XMLHelper getTables(String zDB, String zSchema) {
+        XMLHelper oResponse = null;
+        try {
+            DatabaseMetaData mt = this.getMetaData();
+            ResultSet rs = mt.getTables(zDB, zSchema, null, new String[]{"TABLE"});
+            boolean bTempOra = this.lbIsOracle;
+            this.lbIsOracle = true;
+            oResponse = getDOM(rs);
+            this.lbIsOracle = bTempOra;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+        return oResponse;
+    }
+
+    public XMLHelper getViews(String zSchema) {
+        return getViews(null, zSchema);
+    }
+    public XMLHelper getViews(String zDB, String zSchema) {
+        XMLHelper oResponse = null;
+        try {
+            DatabaseMetaData mt = this.getMetaData();
+            ResultSet rs = mt.getTables(zDB, zSchema, null, new String[]{"VIEW"});
+            oResponse = getDOM(rs);
+        } catch (Exception ex) {
+            logError(ex);
+        }
+        return oResponse;
+    }
+
+    public XMLHelper getSchemas() {
+        XMLHelper oResponse = null;
+        try {
+
+            DatabaseMetaData mt = this.getMetaData();
+            ResultSet rs = mt.getSchemas();
+            oResponse = getDOM(rs);
+
+        } catch (Exception ex) {
+            logError(ex);
+        }
+        return oResponse;
+    }
+
+    public XMLHelper getCatalogs() {
+        XMLHelper oResponse = null;
+        try {
+
+            DatabaseMetaData mt = this.getMetaData();
+            ResultSet rs = mt.getCatalogs();
+            oResponse = getDOM(rs);
+
+        } catch (Exception ex) {
+            logError(ex);
+        }
+        return oResponse;
+    }
+
+    public XMLHelper getExportedKeys(String zTable) throws Exception {
+        try {
+            ResultSet oRS = getMetaData().getExportedKeys(null, null, zTable);
+            return getDOM(oRS);
+        } catch (Exception ex) {
+            handleError(ex);
+            return null;
+        }        
+    } 
+    public XMLHelper getColumns(String zTable) {
+        return getColumns(null, zTable);
+    }
+    public XMLHelper getColumns(String zCatalog, String zTable) {
+        return getColumns(zCatalog, null, zTable);
+    }
+    public XMLHelper getColumns(String zCatalog, String schemaPattern, String zTable) {
+        XMLHelper oResponse = null;
+        try {
+            DatabaseMetaData mt = this.getMetaData();
+            ResultSet rs = mt.getColumns(zCatalog, schemaPattern, zTable,null);
+            boolean bTempOra = this.lbIsOracle;
+            this.lbIsOracle = true;
+            oResponse = getDOM(rs);
+            this.lbIsOracle = bTempOra;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+        return oResponse;
+        
+    }
+    public XMLHelper getTableMetaData(String zTable) throws Exception {
+        try {
+            XMLHelper oResponse = new XMLHelper("response");
+            XMLHelper oTable = oResponse.appendNode("table");
+            oTable.appendAttribute("name", zTable);
+            XMLHelper oCols = oTable.appendNode("columns");
+
+            DatabaseMetaData mt = this.getMetaData();
+            //ResultSet rs = mt.getColumns(null, null, zTable, null);
+            System.out.println(zTable);
+            ResultSet rs = mt.getColumns(null, null, zTable, null);
+            while (rs.next()) {
+                XMLHelper oCol = oCols.appendNode("column");
+                oCol.appendAttribute("name", rs.getString(4));
+                String zTemp = rs.getString(18).toUpperCase();
+                if (zTemp.charAt(0) == 'Y' || zTemp.charAt(0) == 'T' || zTemp.charAt(0) == '1') {
+                    zTemp = "Y";
+                } else {
+                    zTemp = "N";
+                }
+                oCol.appendAttribute("nullable", zTemp);
+                oCol.appendAttribute("pos", rs.getString(17));
+                oCol.appendAttribute("type", rs.getString(5));
+                oCol.appendAttribute("size", rs.getString(7));
+                oCol.appendAttribute("prec", rs.getString(10));
+                oCol.appendAttribute("scale", rs.getString(9));
+            }
+            rs.close();
+
+            XMLHelper oInds = oTable.appendNode("indexes");
+            String zPrevInd = "";
+            XMLHelper oIndex = null;
+            rs = mt.getIndexInfo(null, null, zTable, false, false);
+            while (rs.next()) {
+                String zIndName = rs.getString(6);
+                if (zIndName.equals(zPrevInd) == false) {
+                    oIndex = oInds.appendNode("index");
+                    oIndex.appendAttribute("name", zIndName);
+                    String zTemp = rs.getString(4).toUpperCase();
+                    if (zTemp.charAt(0) == 'Y' || zTemp.charAt(0) == 'T' || zTemp.charAt(0) == '1') {
+                        zTemp = "N";
+                    } else {
+                        zTemp = "Y";
+                    }
+                    oIndex.appendAttribute("unique", zTemp);
+                }
+                XMLHelper oIndCol = oIndex.appendNode("column");
+                oIndCol.appendAttribute("name", rs.getString(9));
+                oIndCol.appendAttribute("type", rs.getString(7));
+                oIndCol.appendAttribute("pos", rs.getString(8));
+                zPrevInd = zIndName;
+            }
+
+            //Get the data
+            XMLHelper oData = oResponse.appendNode("data");
+
+            rs = this.getRS("select * from " + zTable);
+            ResultSetMetaData rm = rs.getMetaData();
+            String zIns = "insert into " + zTable + "(";
+//            DBHelper oDB2 = new DBHelper("derby");
+
+            for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+                if (i > 1) {
+                    zIns += ", ";
+                }
+                zIns += rm.getColumnName(i);
+            }
+            zIns += ") values (";
+
+            while (rs.next()) {
+                String zSQL = zIns;
+                for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+                    if (i > 1) {
+                        zSQL += ", ";
+                    }
+                    String zData = rs.getString(i);
+                    if (zData == null) {
+                        zSQL += "null";
+                    } else {
+                        if (rm.getColumnType(i) == Types.TIMESTAMP) {
+                            SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat + " HH:mm:ss");
+                            zSQL += "'" + sdf.format(rs.getTimestamp(i)) + "'";
+                        } else if (rm.getColumnType(i) == Types.DATE) {
+                            SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat);
+                            zSQL += "'" + sdf.format(rs.getDate(i)) + "'";
+                        } else if (rm.getColumnType(i) == Types.CLOB) {
+                            // read the clob value
+                            Clob oClob = rs.getClob(i);
+                            // Buffer to hold the CLOB data
+                            StringBuilder clobData = new StringBuilder();
+                            // Open the stream to read data
+                            Reader oReader = oClob.getCharacterStream();
+                            //  Buffer size is fixed using the getBufferSize() method which
+                            //  returns the optimal buffer size to read data from the LOB
+                            char[] charbuffer = new char[(int) oClob.length()];
+
+                            // Keep reading from the CLOB and append it to the StringBuilder till
+                            // there is no more to read
+                            int bytesread;
+                            while ((bytesread = oReader.read(charbuffer)) != -1) {
+                                clobData.append(charbuffer, 0, bytesread);
+                            }
+                            zSQL += "'" + clobData.toString().replaceAll("'", "''") + "'";
+                        } else if (rm.getColumnType(i) == Types.VARCHAR || rm.getColumnType(i) == Types.CHAR) {
+                            zSQL += "'" + zData.replaceAll("'", "''") + "'";
+                        } else {
+                            zSQL += zData;
+                        }
+                    }
+                }
+                zSQL += ")";
+                oData.appendNode("row", zSQL);
+            }
+            //oFile.write(zSQL + ";\n");
+            //out.println(zSQL);
+            return oResponse;
+
+        } catch (SQLException ex) {
+            logError(ex);
+            return null;
+        } catch (IOException ex) {
+            logError(ex);
+            return null;
+        }
+
+    }
+
+    public void executeStatement(String zSQL) throws Exception {
+        Statement stmt = getConnection().createStatement();
+        stmt.execute(zSQL);
+//        _command = createSPParams(zSQL);
+//        _command.Command.executeQuery();
+    }
+
+    public void execute(DBParams oCommand) throws Exception {
+        try {
+            oCommand.Command.executeUpdate();
+        } catch (Exception e) {
+            handleError(e);
+        }
+    }
+
+
+    public XMLHelper execute(String zSQL) throws Exception {
+        try {
+            _command = createSPParams(zSQL);
+
+            XMLHelper oResponse = new XMLHelper("response");
+            int iRows = _command.Command.executeUpdate();
+            oResponse.appendAttribute("rows", Integer.toString(iRows));
+            return oResponse;
+        } catch (Exception e) {
+            handleError(e);
+            return null;
+        }
+    }
+
+    public XMLHelper execute(String zSQL, String zID) throws Exception {
+        return execute(zSQL, new String[] {zID});
+    }
+    public XMLHelper execute(String zSQL, String[] aIDs) throws Exception {
+        String[] zIDs = new String[aIDs.length];
+        for (int i=0; i < aIDs.length; i++) {
+            zIDs[i] = aIDs[i].startsWith("@") ? aIDs[i].substring(1) : aIDs[i];
+        }
+
+        try {
+            _command = createSPParams(zSQL, zIDs);
+            XMLHelper oResponse = new XMLHelper("response");
+            int iRows = _command.Command.executeUpdate(); //zSQL, Statement.RETURN_GENERATED_KEYS);
+            oResponse.appendAttribute("rows", Integer.toString(iRows));
+            ResultSet rs = _command.Command.getGeneratedKeys();
+            if (rs.next()) {
+                oResponse.appendAttribute("id", Integer.toString(rs.getInt(1)));
+                for (int id=0; id < aIDs.length; id++) {
+                    _request.setNode(aIDs[id], rs.getString(id+1));
+//                    _request.setNode(aIDs[i], Integer.toString(rs.getInt(i+1)));
+                }
+            }
+            return oResponse;
+        } catch (Exception e) {
+            handleError(e);
+            return null;
+        }
+
+    }
+
+    public XMLHelper executeBatch(String zSQL, String zXPath, String zID) throws SQLException, Exception {
+        return executeBatch(zSQL, zXPath, new String[]{zID});
+    }
+    public XMLHelper executeBatch(String zSQL, String zXPath, String[] aIDs) throws SQLException, Exception {
+        String[] zIDs = new String[aIDs.length];
+        for (int i=0; i < aIDs.length; i++) {
+            zIDs[i] = aIDs[i].startsWith("@") ? aIDs[i].substring(1) : aIDs[i];
+        }
+        try {
+            XMLHelper oResponse = new XMLHelper("response");
+            this.getConnection();
+            if (lbIsSQLServer) {
+                XMLHelper origRequest = this._request;
+                XMLHelper[] aNodes = _request.getNodes(zXPath);
+                for (XMLHelper oEvent : aNodes) {
+                    this.setRequest(oEvent);
+                    this.execute(zSQL, aIDs);
+                }
+                oResponse.appendAttribute("rows", Integer.toString(aNodes.length));
+                this.setRequest(origRequest);
+            } else {
+                _command = createSPParams(zSQL, zXPath, zIDs);
+                int[] iRows = _command.Command.executeBatch();
+                oResponse.appendAttribute("rows", Integer.toString(iRows.length));
+                ResultSet rs = _command.Command.getGeneratedKeys();
+                XMLHelper[] oRows = _request.getNodes(zXPath);
+                int i = 0;
+                while (rs.next()) {
+                    for (int id=0; id < aIDs.length; id++) {
+                        oRows[i].setNode(aIDs[id], rs.getString(id+1));
+    //                    _request.setNode(aIDs[i], Integer.toString(rs.getInt(i+1)));
+                    }
+                    i++;
+                }                
+            }
+            return oResponse;
+        } catch (SQLException e) {
+            handleError(e);
+            return null;
+        }
+    }
+
+    public XMLHelper executeBatch(String zSQL, String zXPath) throws SQLException, Exception {
+        try {
+            _command = createSPParams(zSQL, zXPath);
+            XMLHelper oResponse = new XMLHelper("response");
+            int[] iRows = _command.Command.executeBatch();
+            oResponse.appendAttribute("rows", Integer.toString(iRows.length));
+            return oResponse;
+        } catch (SQLException e) {
+            handleError(e);
+            return null;
+        }
+    }
+
+    public XMLHelper executeBatch(DBParams oCommand, String zXPath) throws SQLException, Exception {
+            addParserParams(zXPath);
+            return executeBatch(oCommand);
+    }
+    public XMLHelper executeBatch(DBParams oCommand) throws SQLException, Exception {
+        try {
+            XMLHelper oResponse = new XMLHelper("response");
+            int[] iRows = oCommand.Command.executeBatch();
+            oResponse.appendAttribute("rows", Integer.toString(iRows.length));
+            return oResponse;
+        } catch (SQLException e) {
+            handleError(e);
+            return null;
+        }
+    }
+
+    public Connection getConnection() throws Exception {
+        return (getConnection(zgSystem));
+    }
+
+    private Connection getConnection(String zSystem) throws Exception {
+        if (oConnection == null || oConnection.isClosed()) {
+            try {
+                Context cx = new InitialContext();
+                DataSource ds = (DataSource) cx.lookup("java:comp/env/jdbc/" + zSystem);
+                oConnection = ds.getConnection();
+                oConnection.setAutoCommit(lbAutoCommit);
+            } catch (Exception e) {
+                try {
+                    Class.forName(getRes("DBDriver"));
+                    String zURL = getRes("DBURL");
+                    lbIsSQLServer = zURL.contains(":sqlserver:");
+                    lbIsOracle = zURL.contains(":oracle:") || zURL.contains(":h2:");
+                    lbIsMysql = zURL.contains(":mysql:");
+                    lbIsPostgres = zURL.contains(":postgresql:");
+                    oConnection = DriverManager.getConnection(zURL, getRes("DBUser"), getRes("DBPassword"));
+                    oConnection.setAutoCommit(lbAutoCommit);
+                } catch (Exception ex) {
+                    handleError(ex);
+                }
+            }
+            if (!lbAutoCommit && _request != null) {
+                _request._con = oConnection;
+            }
+        }
+        return (oConnection);
+    }
+
+    public DatabaseMetaData getMetaData() throws Exception {
+        try {
+            return (getConnection().getMetaData());
+        } catch (Exception ex) {
+            handleError(ex);
+            return null;
+        }
+    }
+
+    public ResultSet getRS(String zSQL) throws Exception {
+        try {
+            _command = createSPParams(zSQL);
+            return (_command.Command.executeQuery());
+        } catch (Exception ex) {
+            handleError(ex);
+            return (null);
+        }
+    }
+
+    public int[] getMaxCols(String zSQL) throws Exception {
+        ResultSet rs = getRS(zSQL);
+        ResultSetMetaData md = rs.getMetaData();
+        int iCols = md.getColumnCount();
+        int[] iMax = new int[iCols];
+        while (rs.next()) {
+            for (int i=0; i < iCols; i++) {
+                String val = rs.getString(i+1);
+                if (val != null &&val.length() > iMax[i]) {
+                    iMax[i] = val.length();
+                }
+            }
+        }
+        return iMax;
+    }
+
+    public void commit() {
+        try {
+            getConnection().commit();
+//            oConnection.close();
+//            oConnection = null;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    public void rollback() {
+        try {
+            getConnection().rollback();
+//            oConnection.close();
+//            oConnection = null;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+    public void setRequest(XMLHelper oRequest) {
+        _request = oRequest;
+    }
+    public void createTable(XMLHelper oMeta) throws Exception {
+        XMLHelper[] aCols = oMeta.getNodes("table/columns/column");
+        HashMap oTypes = this.getTypes();
+        // Create the Table
+        String zSQL = "create table " + oMeta.getString("table/@name") + "(";
+        for (int i = 0; i < aCols.length; i++) {
+            if (i > 0) {
+                zSQL += ",";
+            }
+            zSQL += aCols[i].getString("@name") + " ";
+            Integer iType = aCols[i].getInt("@type");
+            boolean bFound = oTypes.containsKey(iType);
+            if (bFound) {
+                zSQL += oTypes.get(iType);
+                switch (iType) {
+                    case Types.CHAR:
+                    case Types.VARCHAR:
+                        zSQL += "(" + aCols[i].getString("@size") + ")";
+                        break;
+                    case Types.DECIMAL:
+                    case Types.NUMERIC:
+                        zSQL += "(" + aCols[i].getString("@prec") + ", " + aCols[i].getString("@scale") + ")";
+                        break;
+                }
+            }
+            if (aCols[i].getString("@nullable").equals("N")) {
+                zSQL += " not null";
+            }
+        }
+        zSQL += ")";
+        this.execute(zSQL);
+        this.commit();
+
+        // Create the indexes
+        XMLHelper[] aInd = oMeta.getNodes("table/indexes/index");
+        for (XMLHelper oIndex : aInd) {
+            zSQL = "create ";
+            if (oIndex.getString("@unique").equals("Y")) {
+                zSQL += "unique ";
+            }
+            zSQL += "index " + oIndex.getString("@name") + " on " + oMeta.getString("table/@name") + " (";
+            aCols = oIndex.getNodes("column");
+            for (int j = 0; j < aCols.length; j++) {
+                if (j > 0) {
+                    zSQL += ", ";
+                }
+                zSQL += aCols[j].getString("@name");
+            }
+            zSQL += ")";
+            this.execute(zSQL);
+            this.commit();
+        }
+
+        // Create the data
+        XMLHelper[] aData = oMeta.getNodes("data/row");
+        for (XMLHelper oData : aData) {
+            this.execute(oData.getValue());
+        }
+        this.commit();
+    }
+
+    /// <summary>
+    /// Creates Parameters to pass to the passed in command type
+    /// </summary>
+    /// <param name="zCommandText">Can be either a SQL Command or a stored procedure depending on the type</param>
+    /// <param name="tCommandType">The type of command to create parameters for</param>
+    /// <returns>The Parameters Object</returns>
+
+    public DBParams createSPParams(String zSQL) throws Exception {
+        return createSPParams(zSQL, "");
+    }
+
+    public DBParams createSPParams(String zSQL, XMLHelper oNode) throws Exception {
+        _request = oNode;
+        zSQL = parseSQL(zSQL);
+        if (_command != null && _command.Command != null) {
+            _command.Command.close();
+        }
+
+        PreparedStatement oCommand = getConnection().prepareStatement(zSQL);
+        _command = new DBParams(oCommand);
+        addParserParams(oNode);
+
+        return _command;
+    }
+
+    public DBParams createSPParams(String zSQL, String zXPath) throws Exception {
+        if (zSQL != null && zSQL.length() > 0) {
+            if (_request != null) {
+                zSQL = parseSQL(zSQL);
+            }
+            if (_command != null && _command.Command != null) {
+                _command.Command.close();
+            }
+
+            PreparedStatement oCommand = getConnection().prepareStatement(zSQL);
+            _command = new DBParams(oCommand);
+        }
+        if (zXPath.equals("")) {
+            addParserParams();
+        } else {
+            addParserParams(zXPath);
+        }
+        return _command;
+    }
+
+    public DBParams createSPParams(String zSQL, String[] zIDs) throws Exception {
+        return createSPParams(zSQL, null, zIDs);
+    }
+
+    public DBParams createSPParams(String zSQL, String zXPath, String[] zIDs) throws Exception {
+        if (_request != null) {
+            zSQL = parseSQL(zSQL);
+        }
+        if (_command != null && _command.Command != null) {
+            _command.Command.close();
+        }
+
+//        for (int i=0; i < zIDs.length; i++) {
+//            if (zIDs[i].startsWith("@")) {
+//                zIDs[i] = zIDs[i].substring(1);
+//            }
+//        }
+
+        PreparedStatement oCommand = getConnection().prepareStatement(zSQL, zIDs);
+        _command = new DBParams(oCommand);
+        if (zXPath == null || zXPath.equals("")) {
+            addParserParams();
+        } else {
+            addParserParams(zXPath);
+        }
+        return _command;
+    }
+
+    public XMLHelper getHierDOM(String zSQL) throws Exception {
+        XMLHelper oResponse = new XMLHelper("response");
+        XMLHelper oRows = oResponse.appendNode("rows");
+        XMLHelper oRow = null;
+        String zNodeValue;
+
+        ResultSet oRS = getRS(zSQL);
+
+        // Set the start row and max rows
+        int iRow = 0;
+        int iMaxRows = 5000;
+        ResultSetMetaData rm = oRS.getMetaData();
+
+        //  Loop through the recordset and construct the XML DOM
+        while (oRS.next() && iRow < iMaxRows) {
+            for (int i = 1; i < rm.getColumnCount() + 1; i++) {
+                if (rm.getColumnType(i) == Types.TIMESTAMP || rm.getColumnType(i) == Types.DATE) {
+                    SimpleDateFormat sdf = new SimpleDateFormat(lzDateFormat);
+                    if (oRS.getDate(i) == null) {
+                        zNodeValue = "";
+                    } else {
+                        zNodeValue = sdf.format(oRS.getDate(i));
+                    }
+                } else {
+                    zNodeValue = oRS.getString(i);
+                }
+                String zNodeName = rm.getColumnLabel(i).toLowerCase().replaceAll("\"", "");
+                if (lbUpperCaseNodes) {
+                    zNodeName = zNodeName.toUpperCase();
+                }
+                if (i == 1) {
+                    oRow = oRows;
+                }
+                oRow = oRow.getOrAddNode(zNodeName, zNodeValue);
+                // Split the Name by "/"
+            }
+            iRow++;
+        }
+        //  If total is to be shown move to the end of the recordset
+        oRS.close();
+        return oResponse;
+
+    }
+    public void setAutoCommit(boolean bAC) throws SQLException{
+        lbAutoCommit = bAC;
+        oConnection.setAutoCommit(bAC);
+    }
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        try {
+            DBHelper o = new DBHelper();
+            String s
+                    = "select  * "
+                    + "from    tbcdg_field f "
+                    + "where   f.table_name = v:table_name "
+                    + "[and scrn_type = v:scrn_type "
+                    + "[and scrn_type = v:scrn_type1]] "
+                    + "[and column_len :op_scrn_type i:column_len[ and i:column_len1]] ";
+            System.out.println(o.parseSQL(s));
+
+            DBHelper oDB = new DBHelper("10HS");
+            DBParams oCommand = oDB.createSPParams("{call InvoiceReport(?, ?)}");
+            //oCommand.add("@InvoiceDate", DBParams.DataType.DateTime, new java.sql.Date(new SimpleDateFormat("dd-MMM-yyyy").parse("31-MAR-2009").getTime()));
+            oCommand.add("@InvoiceDate", DBParams.DataType.DateTime, "31-MAR-2009");
+            oCommand.add("@InvType", DBParams.DataType.Int, 2);
+            XMLHelper oXML = oDB.getDOM(oCommand);
+            System.out.println(oXML);
+            return;
+        } catch (Exception ex) {
+            System.out.println(ex);
+        }
+
+        long lStart = new java.util.Date().getTime();
+
+        try {
+            DBHelper oDB = new DBHelper();
+            ResultSet rs = oDB.getRS("select table_name as \"@name\", table_desc as desc, no_keys, null as ns from tbcdg_form");
+            while (rs.next()) {
+                String s = rs.getString(1);
+            }
+            rs.close();
+        } catch (Exception ex) {
+            System.out.println(ex.getMessage());
+        }
+
+        //System.out.println(oDOM.getRootXML());
+        System.out.println((new java.util.Date().getTime() - lStart) / 1000.00);
+
+        try {
+            DBHelper oDB = new DBHelper();
+            lStart = new java.util.Date().getTime();
+            ResultSet rs = oDB.getRS("select table_name as \"@name\", table_desc as descr, no_keys, null as ns from tbcdg_form");
+            XMLHelper oDOM = oDB.getDOM(rs, 0, 20, true, "forms", "table", false);
+            System.out.println((new java.util.Date().getTime() - lStart) / 1000.00);
+
+            lStart = new java.util.Date().getTime();
+            rs = oDB.getRS("select table_name as \"@name\", table_desc as descr, no_keys, null as ns from tbcdg_form");
+            oDOM = oDB.getDOM(rs, 0, 20, true, "forms", "table", false);
+            System.out.println((new java.util.Date().getTime() - lStart) / 1000.00);
+            System.out.println(oDOM.getRootXML());
+        } catch (Exception ex) {
+            System.out.println(ex.getMessage());
+        }
+        //Oracle test
+/*        try {
+         oDB = new DBHelper("cims");
+         CallableStatement stmt = oDB.getConnection().prepareCall("BEGIN PKG_SCHEMES.spFetchCustomerHierSchemes(?,?); END;");
+         stmt.setInt(1, 5606585); // DEPTNO
+         stmt.registerOutParameter(2, oracle.jdbc.driver.OracleTypes.CURSOR); //REF CURSOR
+         stmt.execute();
+         rs = (ResultSet) stmt.getObject(2);
+         oDOM = oDB.getDOM(rs,0, 99999, true, "rows",  "row", false);
+         System.out.println(oDOM.getRootXML());
+         }
+         catch (SQLException e) {
+         System.out.println(e.getLocalizedMessage());
+         }
+         */
+        try {
+            DBHelper oDB = new DBHelper("tb");
+            XMLHelper oDom = oDB.getDOM("select * from sd_table");
+            System.out.println(oDom.getXML());
+            ResultSet rs = oDB.getRS("select table_id, column_id as \"@id\", descr,column_type_lv, column_len from sd_column");
+            oDB.appendToDOM(oDom, "rows/row", "table_id", rs, "columns", "column", 0, 9999999, false, false);
+            System.out.println(oDom.getXML());
+            oDB = new DBHelper("tb");
+            Connection oCon = oDB.getConnection();
+            DatabaseMetaData mt = oCon.getMetaData();
+            String[] types
+                    = {
+                        "TABLE"
+                    };
+            rs = mt.getTables(null, null, "%", types);
+
+            oDom = oDB.getDOM(rs, 0, 9999999, false, "rows", "row", false);
+            System.out.println(oDom.getXML());
+            XMLHelper req = new XMLHelper().createStandardRequest("test", "1", "tb");
+            req.appendNode("table_name", "tbcdg_field");
+            req.appendNode("scrn_type", "PIK");
+            req.appendNode("op_scrn_type", "=");
+            oDB = new DBHelper(req);
+            System.out.println(oDB.getDOM("select * from tbcdg_field where table_name = ':table_name' and scrn_type = ':scrn_type'").getXML());
+            System.out.println(oDB.getDOM("select * from tbcdg_field where table_name = v:table_name[ and scrn_type = v:scrn_type[ and scrn_type = v:scrn_type1]]").getXML());
+            System.out.println(oDB.parseSQL("select * from tbcdg_field where table_name = ':table_name' and scrn_type = ':scrn_type'"));
+            System.out.println(oDB.parseSQL("select * from tbcdg_field where table_name = v:table_name[ and scrn_type = v:scrn_type[ and scrn_type = v:scrn_type1]]"));
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("select  * ");
+            sb.append("from    tbcdg_field f ");
+            sb.append("where   f.table_name = v:table_name ");
+            sb.append("[and scrn_type = v:scrn_type ");
+            sb.append("[and scrn_type = v:scrn_type1]] ");
+            sb.append("[and column_len :op_scrn_type i:column_len[ and i:column_len1]] ");
+            System.out.println(oDB.parseSQL(sb.toString()));
+        } catch (Exception ex) {
+            System.out.println(ex.getMessage());
+        }
+
+//Test a diffrernt database
+//        lStart = new java.util.Date().getTime();
+//        oDB = new DBHelper("tb");
+//        XMLHelper oMeta = oDB.getTableMetaData("tbcdg_form");
+//        System.out.println(oMeta.getXML());
+//
+//        XMLHelper[] aCols = oMeta.getNodes("table/columns/column");
+//        DBHelper oTB = new DBHelper("derby");
+//        HashMap oTypes = oTB.getTypes();
+//        String zSQL = "create table " + oMeta.getString("table/@name") + "(";
+//        for (int i=0; i < aCols.length; i++)
+//        {
+//            System.out.print(aCols[i].getString("@name") + " ");
+//            if (i > 0)
+//                zSQL += ",";
+//            zSQL += aCols[i].getString("@name") + " ";
+//            Integer iType = new Integer(aCols[i].getInt("@type"));
+//            boolean bFound = oTypes.containsKey(iType);
+//            if (bFound)
+//            {
+//                System.out.print(oTypes.get(iType));
+//                zSQL += oTypes.get(iType);
+//                switch (iType.intValue())
+//                {
+//                    case Types.CHAR :
+//                    case Types.VARCHAR :
+//                        System.out.print("(" + aCols[i].getString("@size")+ ")");
+//                        zSQL += "(" + aCols[i].getString("@size")+ ")";
+//                        break;
+//                    case Types.DECIMAL :
+//                    case Types.NUMERIC :
+//                        System.out.print("(" + aCols[i].getString("@prec") + ", " + aCols[i].getString("@scale") + ")");
+//                        zSQL += "(" + aCols[i].getString("@prec") + ", " + aCols[i].getString("@scale") + ")";
+//                        break;
+//                }
+//            }
+//            if (aCols[i].getString("@nullable").equals("N"))
+//                zSQL += " not null";
+//            System.out.println();
+//        }
+//        zSQL += ")";
+//        System.out.println(zSQL);
+//        oTB.execute(zSQL);
+//        oTB.commit();
+//        DBHelper oDB = new DBHelper();
+//        System.out.println("default = " + oDB.getTypes());
+//        oDB = new DBHelper("cims");
+//        System.out.println("cims = " + oDB.getTypes());
+//        oDB = new DBHelper("derby");
+//        System.out.println("derby = " + oDB.getTypes());
+    //Stored Proc
+/*        oDB = new DBHelper("cims");
+         try
+         {
+
+         // Setup the call.
+         CallableStatement toesUp
+         = oDB.getConnection().prepareCall("BEGIN pkg_customers.spViewCustomer( ?, ?, ?); END;");
+         //            toesUp.registerOutParameter(1, Types.OTHER);
+         toesUp.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
+
+         toesUp.setLong(2, 2398500);
+         toesUp.setLong(3, 44611);
+         toesUp.execute();
+
+         rs = (ResultSet) toesUp.getObject(1);
+
+         oDOM = oDB.getDOM(rs, 0,0,false,"rows","row",false);
+         System.out.println(oDOM.getXML());
+         } catch (SQLException ex)
+         {
+         ex.printStackTrace();
+         }
+         */
+    }
+}

+ 222 - 0
src/com/cloudsoft/utils/DBParams.java

@@ -0,0 +1,222 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import oracle.jdbc.OracleTypes;
+/**
+ *
+ * @author paul
+ */
+public class DBParams
+{
+
+
+    /// <summary>
+    /// Database Parameters class.
+    /// Allows parameters to be added to a DBHelper.
+    /// Can only be instatiated from a DBHelper.
+    /// </summary>
+        /// <summary>
+        /// DataType enumerator.
+        /// </summary>
+        /// <remarks>
+        /// <list type="bullet">
+        /// <item><term>VarChar</term><description> - Varchar (string)</description></item>
+        /// <item><term>Long</term><description> - Long integer</description></item>
+        /// <item><term>Double</term><description> - Double (float)</description></item>
+        /// <item><term>DateTime</term><description> - Date</description></item>
+        /// <item><term>LongVarChar</term><description> - Clob</description></item>
+        /// </list>
+        /// </remarks>
+        public enum DataType {
+            /// <summary>Varchar</summary>
+            VarChar,
+            /// <summary>Long</summary>
+            Int,
+            /// <summary>Double</summary>
+            Double,
+            /// <summary>Float</summary>
+            Float,
+            /// <summary>DateTime</summary>
+            DateTime,
+            /// <summary>LongVarChar</summary>
+            LongVarChar,
+            Cursor
+        };
+        protected PreparedStatement Command;
+        private int _cnt = 0;
+        private boolean _hasCursor = false;
+        private HashMap<String, Integer> oKeys = new HashMap<String, Integer>();
+        private SimpleDateFormat sdf1 = null;
+        private SimpleDateFormat sdf2 = null;
+        List<SimpleDateFormat> datePatterns = null;
+        private int oleType(DataType eDT)
+        {
+            switch (eDT)
+            {
+                case DateTime: return Types.TIMESTAMP;
+                case Int: return Types.BIGINT;
+                case Double: return Types.DOUBLE;
+                case Float: return Types.FLOAT;
+                case LongVarChar: return Types.LONGVARCHAR;
+                case Cursor: return OracleTypes.CURSOR;
+                default: return Types.VARCHAR;
+            }
+        }
+
+        private int pSize(DataType eDT, Object oValue)
+        {
+            switch (eDT)
+            {
+                case DateTime: return 20;
+                case Int: return 10;
+                case Double:
+                case Float: return 16;
+                default: return (oValue.toString().length());
+            }
+        }
+
+        protected DBParams(PreparedStatement oCommand)
+        {
+            Command = oCommand;
+         //   if (isRS)
+         //       Command.registerOutParameter(++_cnt, Types.OTHER);
+        }
+        protected boolean hasCursor()
+        {
+            return _hasCursor;
+        }
+        /// <summary>
+        /// Adds a Input Parameter to the DBHelper
+        /// </summary>
+        /// <param name="zParamName">Parameter Name</param>
+        public void add(String zParamName) throws SQLException
+        {
+            oKeys.put(zParamName, ++_cnt);
+        }
+        /// <summary>
+        /// Adds a Input Parameter to the DBHelper
+        /// </summary>
+        /// <param name="zParamName">Parameter Name</param>
+        /// <param name="eDT">DataType</param>
+        /// <param name="oValue">Value of the Parameter</param>
+        public void add(String zParamName, DataType eDT, Object oValue) throws SQLException
+        {
+//            Command.setObject(++_cnt, oValue, oleType(eDT)); //, pSize(eDT, oValue)
+            oKeys.put(zParamName, ++_cnt);
+//            switch (eDT)
+//            {
+//                case DateTime: Command.setDate(_cnt, (Date)oValue);
+//                    break;
+//                default:
+//                    break;
+//            }
+            Command.setObject(_cnt, oValue); //, pSize(eDT, oValue)
+
+          }
+
+        public void set(String zParamName, Object oValue) throws SQLException
+        {
+            set(zParamName, oValue, null);
+        }
+        public void set(String zParamName, Object oValue, Integer iType) throws SQLException
+        {
+            Integer iVal = oKeys.get(zParamName);
+            if (iVal == null)
+            {
+                oKeys.put(zParamName, ++_cnt);
+                iVal = _cnt;
+            }
+            if (iType == null)
+                Command.setObject(iVal, oValue);
+            else
+                Command.setObject(iVal, oValue, iType);
+        }
+        public void set(int iParam, Object oValue) throws SQLException
+        {
+            set(iParam, oValue, null);
+        }
+        public void set (int iParam, int iType, String val) throws SQLException {
+            Object oVal = val;
+            if (val == null || val.length() == 0) {
+                oVal = null;
+            } else {
+                switch (iType) {
+                    case Types.BIGINT : oVal = Long.parseLong(val);
+                        break;
+                    case Types.TIMESTAMP : 
+                            oVal = parseDate(val);
+                        break;
+                    case Types.FLOAT : oVal = Float.parseFloat(val);
+                        break;
+                    case Types.DOUBLE : oVal = Double.parseDouble(val);
+                        break;
+                }
+            }
+            set(iParam, oVal, iType);
+        }
+        public void set(int iParam, Object oValue, Integer iType) throws SQLException
+        {
+            if (iType == null)
+                Command.setObject(iParam, oValue);
+//           else if (iType == Types.TIMESTAMP)
+//                Command.setDate(iParam, (DateoValue);
+            else
+                Command.setObject(iParam, oValue, iType);
+        }
+        public void addBatch() throws Exception
+        {
+            Command.addBatch();
+        }
+        public Timestamp parseDate(String zDate) {
+            if (datePatterns == null) {
+                datePatterns = new ArrayList();
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
+//                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
+                datePatterns.add(new SimpleDateFormat("dd/MM/yyyy' 'HH:mm:ss"));
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"));
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));
+//                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss.SSS'Z'"));
+//                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss'Z'"));
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss.SSS"));
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"));
+//                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS'Z'"));
+//                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss'Z'"));
+                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS"));
+                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss"));
+//                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd' 'HH:mm:ss.SSS'Z'"));
+//                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd' 'HH:mm:ss'Z'"));
+                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd' 'HH:mm:ss.SSS"));
+                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd' 'HH:mm:ss"));
+                datePatterns.add(new SimpleDateFormat("yyyy-MM-dd"));
+                datePatterns.add(new SimpleDateFormat("yyyy/MM/dd"));
+                datePatterns.add(new SimpleDateFormat("dd-MMMM-yyyy' 'HH:mm:ss"));
+                datePatterns.add(new SimpleDateFormat("dd-MMMM-yyyy"));
+            }
+            
+            for (int i=0; i < datePatterns.size(); i++) {
+                SimpleDateFormat df = datePatterns.get(i);
+                try {
+                    Timestamp dt = new Timestamp(df.parse(zDate).getTime());
+                    if (i != 0 && df.toPattern().length() > 13) {
+                        datePatterns.remove(i);
+                        datePatterns.add(0, df);
+                    }
+                    return dt;
+                } catch (Exception ex) {
+                }
+            }
+            return null;    
+        }
+    }
+

+ 357 - 0
src/com/cloudsoft/utils/DeepZoom.java

@@ -0,0 +1,357 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import javax.imageio.ImageIO;
+import java.util.Iterator;
+import java.util.Vector;
+/**
+ *
+ * @author Administrator
+ */
+public class DeepZoom 
+{
+    static final String xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
+    static final String schemaName = "http://schemas.microsoft.com/deepzoom/2009";
+
+    private enum CmdParseState { DEFAULT, OUTPUTDIR, TILESIZE, OVERLAP, INPUTFILE };
+    static Boolean deleteExisting = true;
+    static String tileFormat = "jpg";
+
+    // The following can be overriden/set by the indicated command line arguments
+    static int tileSize = 256;            // -tilesize
+    static int tileOverlap = 1;           // -overlap
+    static File outputDir = null;         // -outputdir or -o
+    static Boolean verboseMode = false;   // -verbose or -v
+    static Boolean debugMode = false;     // -debug
+    static Vector<File> inputFiles = new Vector<File>();// must follow all other args
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+      
+        try {
+            try {
+                parseCommandLine(args);
+                if (outputDir == null)
+                    outputDir = new File(".");
+                if (debugMode) {
+                    System.out.printf("tileSize=%d ", tileSize);
+                    System.out.printf("tileOverlap=%d ", tileOverlap);
+                    System.out.printf("outputDir=%s\n", outputDir.getPath());
+                }
+
+            } catch (Exception e) {
+                System.out.println("Invalid command line: " + e.getMessage());
+                return;
+            }
+
+            if (!outputDir.exists())
+                throw new FileNotFoundException("Output directory does not exist: "
+                                                + outputDir.getPath());
+            if (!outputDir.isDirectory())
+                throw new FileNotFoundException("Output directory is not a directory: "
+                                                + outputDir.getPath());
+
+            Iterator<File> itr = inputFiles.iterator();
+            while (itr.hasNext())
+                 processImageFile(itr.next(), outputDir);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Process the command line arguments
+     * @param args the command line arguments
+     */
+    private static void parseCommandLine(String[] args) throws Exception {
+        CmdParseState state = CmdParseState.DEFAULT;
+        for (int count = 0; count < args.length; count++) {
+            String arg = args[count];
+            switch (state) {
+              case DEFAULT:
+                  if (arg.equals("-verbose") || arg.equals("-v"))
+                      verboseMode = true;
+                  else if (arg.equals("-debug")) {
+                      verboseMode = true;
+                      debugMode = true;
+                  }
+                  else if (arg.equals("-outputdir") || arg.equals("-o"))
+                      state = CmdParseState.OUTPUTDIR;
+                  else if (arg.equals("-tilesize"))
+                      state = CmdParseState.TILESIZE;
+                  else if (arg.equals("-overlap"))
+                      state = CmdParseState.OVERLAP;
+                  else
+                      state = CmdParseState.INPUTFILE;
+                  break;
+              case OUTPUTDIR:
+                  outputDir = new File(arg);
+                  state = CmdParseState.DEFAULT;
+                  break;
+              case TILESIZE:
+                  tileSize = Integer.parseInt(arg);
+                  state = CmdParseState.DEFAULT;
+                  break;
+              case OVERLAP:
+                  tileOverlap = Integer.parseInt(arg);
+                  state = CmdParseState.DEFAULT;
+                  break;
+            }
+            if (state == CmdParseState.INPUTFILE) {
+                File inputFile = new File(arg);
+                if (!inputFile.exists())
+                    throw new FileNotFoundException("Missing input file: " + inputFile.getPath());
+                inputFiles.add(inputFile);
+            }
+        }
+        if (inputFiles.size() == 0)
+            throw new Exception("No input files given");
+    }
+
+    /**
+     * Process the given image file, producing its Deep Zoom output files
+     * in a subdirectory of the given output directory.
+     * @param inFile the file containing the image
+     * @param outputDir the output directory
+     */
+    public static void processImageFile(File inFile, File outputDir) throws IOException {
+        if (verboseMode)
+             System.out.printf("Processing image file: %s\n", inFile);
+
+        String fileName = inFile.getName();
+        String nameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
+        String pathWithoutExtension = outputDir + File.separator + nameWithoutExtension;
+
+        BufferedImage image = loadImage(inFile);
+
+        int originalWidth = image.getWidth();
+        int originalHeight = image.getHeight();
+
+        double maxDim = Math.max(originalWidth, originalHeight);
+
+        int nLevels = (int)Math.ceil(Math.log(maxDim) / Math.log(2));
+
+        if (debugMode)
+            System.out.printf("nLevels=%d\n", nLevels);
+
+        // Delete any existing output files and folders for this image
+
+        File descriptor = new File(pathWithoutExtension + ".xml");
+        if (descriptor.exists()) {
+            if (deleteExisting)
+                deleteFile(descriptor);
+            else
+                throw new IOException("File already exists in output dir: " + descriptor);
+        }
+
+        File imgDir = new File(pathWithoutExtension);
+        if (imgDir.exists()) {
+            if (deleteExisting) {
+                if (debugMode)
+                    System.out.printf("Deleting directory: %s\n", imgDir);
+                deleteDir(imgDir);
+            } else
+                throw new IOException("Image directory already exists in output dir: " + imgDir);
+        }
+
+        imgDir = createDir(outputDir, nameWithoutExtension);
+
+        double width = originalWidth;
+        double height = originalHeight;
+
+        for (int level = nLevels; level >= 0; level--) {
+            int nCols = (int)Math.ceil(width / tileSize);
+            int nRows = (int)Math.ceil(height / tileSize);
+            if (debugMode)
+                System.out.printf("level=%d w/h=%f/%f cols/rows=%d/%d\n",
+                                   level, width, height, nCols, nRows);
+            
+            File dir = createDir(imgDir, Integer.toString(level));
+            for (int col = 0; col < nCols; col++) {
+                for (int row = 0; row < nRows; row++) {
+                    BufferedImage tile = getTile(image, row, col);
+                    saveImage(tile, dir + File.separator + col + '_' + row);
+                }
+            }
+
+            // Scale down image for next level
+            width = Math.ceil(width / 2);
+            height = Math.ceil(height / 2);
+//            if (width > 10 && height > 10) {
+//                // resize in stages to improve quality
+//                image = resizeImage(image, width * 1.66, height * 1.66);
+//                image = resizeImage(image, width * 1.33, height * 1.33);
+//            }
+            image = resizeImage(image, width, height);
+        }
+
+        saveImageDescriptor(originalWidth, originalHeight, descriptor);
+    }
+
+
+    /**
+     * Delete a file
+     * @param path the path of the directory to be deleted
+     */
+    private static void deleteFile(File file) throws IOException {
+         if (!file.delete())
+             throw new IOException("Failed to delete file: " + file);
+    }
+
+    /**
+     * Recursively deletes a directory
+     * @param path the path of the directory to be deleted
+     */
+    private static void deleteDir(File dir) throws IOException {
+        if (!dir.isDirectory())
+            deleteFile(dir);
+        else {
+            for (File file : dir.listFiles()) {
+               if (file.isDirectory())
+                   deleteDir(file);
+               else
+                   deleteFile(file);
+            }
+            if (!dir.delete())
+                throw new IOException("Failed to delete directory: " + dir);
+        }
+    }
+
+    /**
+     * Creates a directory
+     * @param parent the parent directory for the new directory
+     * @param name the new directory name
+     */
+    private static File createDir(File parent, String name) throws IOException {
+        assert(parent.isDirectory());
+        File result = new File(parent + File.separator + name);
+        if (!result.mkdir())
+           throw new IOException("Unable to create directory: " + result);
+        return result;
+    }
+
+    /**
+     * Loads image from file
+     * @param file the file containing the image
+     */
+    private static BufferedImage loadImage(File file) throws IOException {
+        BufferedImage result = null;
+        try {
+            result = ImageIO.read(file);
+        } catch (Exception e) {
+            throw new IOException("Cannot read image file: " + file);
+        }
+        return result;
+    }
+
+    /**
+     * Gets an image containing the tile at the given row and column
+     * for the given image.
+     * @param img - the input image from whihc the tile is taken
+     * @param row - the tile's row (i.e. y) index
+     * @param col - the tile's column (i.e. x) index
+     */
+    private static BufferedImage getTile(BufferedImage img, int row, int col) {
+        int x = col * tileSize - (col == 0 ? 0 : tileOverlap);
+        int y = row * tileSize - (row == 0 ? 0 : tileOverlap);
+        int w = tileSize + (col == 0 ? 1 : 2) * tileOverlap;
+        int h = tileSize + (row == 0 ? 1 : 2) * tileOverlap;
+
+        if (x + w > img.getWidth())
+            w = img.getWidth() - x;
+        if (y + h > img.getHeight())
+            h = img.getHeight() - y;
+
+        if (debugMode)
+            System.out.printf("getTile: row=%d, col=%d, x=%d, y=%d, w=%d, h=%d\n",
+                              row, col, x, y, w, h);
+        
+        assert(w > 0);
+        assert(h > 0);
+
+        BufferedImage result = new BufferedImage(w, h, img.getType());
+        Graphics2D g = result.createGraphics();
+        g.drawImage(img, 0, 0, w, h, x, y, x+w, y+h, null);
+
+        return result;
+    }
+
+    /**
+     * Returns resized image
+     * NB - useful reference on high quality image resizing can be found here:
+     *   http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
+     * @param width the required width
+     * @param height the frequired height
+     * @param img the image to be resized
+     */
+    private static BufferedImage resizeImage(BufferedImage img, double width, double height) {
+        int w = (int)width;
+        int h = (int)height;
+        BufferedImage result = new BufferedImage(w, h, img.getType());
+        Graphics2D g = result.createGraphics();
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                           RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+        g.drawImage(img, 0, 0, w, h, 0, 0, img.getWidth(), img.getHeight(), null);
+        return result;
+    }
+
+    /**
+     * Saves image to the given file
+     * @param img the image to be saved
+     * @param path the path of the file to which it is saved (less the extension)
+     */
+    private static void saveImage(BufferedImage img, String path) throws IOException {
+        File outputFile = new File(path + "." + tileFormat);
+        try {
+            ImageIO.write(img, tileFormat, outputFile);
+        } catch (IOException e) {
+            throw new IOException("Unable to save image file: " + outputFile);
+        }
+    }
+
+    /**
+     * Write image descriptor XML file
+     * @param width image width
+     * @param height image height
+     * @param file the file to which it is saved
+     */
+    private static void saveImageDescriptor(int width, int height, File file) throws IOException {
+        Vector lines = new Vector();
+        lines.add(xmlHeader);
+        lines.add("<Image TileSize=\"" + tileSize + "\" Overlap=\"" + tileOverlap +
+                  "\" Format=\"" + tileFormat + "\" ServerFormat=\"Default\" xmnls=\"" +
+                  schemaName + "\">");
+        lines.add("<Size Width=\"" + width + "\" Height=\"" + height + "\" />");
+        lines.add("</Image>");
+        saveText(lines, file);
+    }
+
+    /**
+     * Saves strings as text to the given file
+     * @param lines the image to be saved
+     * @param file the file to which it is saved
+     */
+    private static void saveText(Vector lines, File file) throws IOException {
+        try {
+            FileOutputStream fos = new FileOutputStream(file);
+            PrintStream ps = new PrintStream(fos);
+            for (int i = 0; i < lines.size(); i++)
+                ps.println((String)lines.get(i));
+        } catch (IOException e) {
+            throw new IOException("Unable to write to text file: " + file);
+        }
+    }
+    
+}

+ 83 - 0
src/com/cloudsoft/utils/EncryptedProperties.java

@@ -0,0 +1,83 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.util.Properties;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEParameterSpec;
+
+/**
+ *
+ * @author Paul
+ */
+public class EncryptedProperties extends Properties {
+
+    private Cipher encrypter, decrypter;
+    private static byte[] salt = {(byte) 0x00, 0x04, 0x00, 0x07, 0x01, 0x09, 0x06, 0x07};  // make up your own
+
+    public EncryptedProperties() {
+        this(salt);
+    }
+    public EncryptedProperties(byte[] bSalt) {
+        try {
+        String pw = "";
+        int is = 80;
+        while (pw.length() < 20) {
+            is = is + pw.length() * ((pw.length()%2 == 1) ? -1:1);
+            pw += (char) is;
+        }
+        PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(bSalt, 20);
+        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
+        SecretKey k = kf.generateSecret(new javax.crypto.spec.PBEKeySpec(pw.toCharArray()));
+        encrypter = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");
+        decrypter = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");
+        encrypter.init(Cipher.ENCRYPT_MODE, k, ps);
+        decrypter.init(Cipher.DECRYPT_MODE, k, ps);
+        } catch (Exception ex) {
+            System.out.println(ex.getMessage());
+        }
+    }
+
+    public String getProperty(String key) {
+        try {
+            return decrypt(super.getProperty(key));
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't decrypt property");
+        }
+    }
+
+    public synchronized Object setProperty(String key, String value) {
+        return setProperty(key, value, true);
+    }
+    public synchronized Object setProperty(String key, String value, boolean bEncrypt) {
+        try {
+            return super.setProperty(key, bEncrypt ? encrypt(value) : value);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't encrypt property");
+        }
+    }
+    public synchronized Object setNormalProperty(String key, String value) {
+        try {
+            return super.setProperty(key, value);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't encrypt property");
+        }
+    }
+
+    private synchronized String decrypt(String str) throws Exception {
+        byte[] dec = Base64.decode(str);
+        byte[] utf8 = decrypter.doFinal(dec);
+        return new String(utf8, "UTF-8");
+    }
+
+    private synchronized String encrypt(String str) throws Exception {
+        byte[] utf8 = str.getBytes("UTF-8");
+        byte[] enc = encrypter.doFinal(utf8);
+        return Base64.encode(enc);
+    }
+}

+ 514 - 0
src/com/cloudsoft/utils/ErrHelper.java

@@ -0,0 +1,514 @@
+/*
+ * ErrHelper.java
+ *
+ * Created on 15 October 2007, 12:39
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+import java.util.logging.StreamHandler;
+import java.util.regex.Pattern;
+import java.util.zip.GZIPInputStream;
+
+/**
+ *
+ * @author paul
+ */
+public class ErrHelper {
+
+    private ResourceBundle _resourceMan;
+    private ResourceBundle _res;
+    private Properties _props;
+    private InputStream _propStream;
+
+    private final HashMap<String, Date> oStats = new HashMap<>();
+    private final DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    public enum ErrorType {
+
+        System, Business, Information
+    };
+
+    public enum FormAction {
+
+        Load, New, Save, Copy, Delete;
+
+        public static FormAction toAction(String zAction) {
+            try {
+                zAction = zAction.substring(0, 1).toUpperCase() + zAction.substring(1);
+                return valueOf(zAction);
+            } catch (Exception ex) {
+                return Load;
+            }
+        }
+    };
+    public String zgSystem = "CS";
+    protected Logger logger = Logger.getLogger("");
+
+    /**
+     * Creates a new instance of ErrHelper
+     */
+    public ErrHelper() {
+    }
+
+    /**
+     * Handles an unexpected error and throws an exception
+     *
+     * @param ex The caught Exception
+     * @return a String
+     * @throws java.lang.Exception
+     */
+    public void setOutput(PrintStream out) {
+        logger.setUseParentHandlers(false);
+        logger.setLevel(Level.WARNING);
+        logger.addHandler(new StreamHandler(out, new SimpleFormatter()));
+    }
+
+    public XMLHelper handle(Exception ex) throws Exception {
+        handleError(ex, ErrorType.System);
+        return null;
+    }
+
+    /**
+     * Handles an unexpected error and throws an exception
+     *
+     * @param ex The caught Exception
+     * @return a String
+     * @throws java.lang.Exception
+     */
+    public String handleError(Exception ex) throws Exception {
+        return handleError(ex, ErrorType.System);
+    }
+
+    /**
+     * Handles an unexpected error and throws an exception
+     *
+     * @param ex The caught Exception
+     * @param et Error Type
+     * @return a String
+     * @throws java.lang.Exception
+     */
+    public String handleError(Exception ex, ErrorType et) throws Exception {
+        XMLHelper oError = new XMLHelper();
+        if (oError.load(ex.getMessage()) == false) {
+            String zType = "SYSTEMERROR";
+            switch (et) {
+                case Business:
+                    zType = "BUSINESSEXCEPTION";
+                    break;
+                case Information:
+                    zType = "INFORMATION";
+                    break;
+            }
+            StackTraceElement[] oST = ex.getStackTrace();
+            int iFrame = 0;
+
+            String zClass = this.getClass().getName();
+            for (iFrame = 0; iFrame < oST.length; iFrame++) {
+                if (oST[iFrame].getClassName().equals(zClass)) {
+                    break;
+                }
+            }
+            oError.createRoot("utils");
+            oError = oError.appendNode("error");
+            Date now = new Date();
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            oError.appendAttribute("time", sdf.format(now));
+            oError.appendAttribute("type", zType);
+            oError.appendAttribute("class", zClass);
+            oError.appendAttribute("method", oST[iFrame].getMethodName());
+            oError.appendNode("source", zClass);
+            oError.appendNode("description", ex.getMessage());
+//            StringWriter zST = new StringWriter();
+//            PrintWriter pw = new PrintWriter(zST, true);
+//            ex.printStackTrace(pw);
+//            oError.appendNode("stack_trace", zST.toString());
+            if (zType.equals("SYSTEMERROR")) {
+                logError(ex);
+            }
+        }
+        //Console.Out.WriteLine(ex.GetType().ToString() + " Exception : (" + ex.Source + ") " + ex.Message);
+        throw new Exception(oError.getRootXML());
+    }
+
+    /**
+     * Throws an business error.
+     *
+     * @param zMessage The error message.
+     * @throws java.lang.Exception
+     */
+    public void throwError(String zMessage) throws Exception {
+        throwError(zMessage, ErrorType.Business);
+    }
+
+    /**
+     * Throws an error.
+     *
+     * @param zMessage The error message.
+     * @param et The error type.
+     * @throws java.lang.Exception
+     */
+    public void throwError(String zMessage, ErrorType et) throws Exception {
+        handleError(new Exception(zMessage), et);
+    }
+
+    public void validatePayload(XMLHelper oRequest) {
+    }
+
+    public XMLHelper validatePayload(String zRequest) {
+        XMLHelper oRequest = new XMLHelper(zRequest);
+        return oRequest;
+    }
+
+    private ResourceBundle ResourceManager() {
+        if (_resourceMan == null) {
+            _resourceMan = ResourceBundle.getBundle(this.getClass().getName());
+        }
+        return _resourceMan;
+    }
+
+    private ResourceBundle SystemResource() {
+        if (_res == null) {
+            _res = ResourceBundle.getBundle(zgSystem);
+        }
+        return _res;
+    }
+
+    public String getMethodResource() {
+        String zMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
+        return getResource(zMethod);
+    }
+
+    public String getResource(String zMethod) {
+        return ResourceManager().getString(zMethod);
+    }
+
+    public XMLHelper getDBSystems() throws Exception {
+        XMLHelper oXML = new XMLHelper("response");
+        XMLHelper oRows = oXML.appendNode("rows");
+        ResourceList rl = new ResourceList();
+        for (String name : rl.getResources(Pattern.compile(".*\\.properties"))) {
+            if (name.endsWith(".properties")) {
+                File f = new File(name);
+                String zProp = f.getName().replace(".properties", "");
+                setRes(zProp);
+                if (getRes("DBURL") != null) {
+                    oRows.appendNode("row").appendNode("system", zProp);
+                }
+            }
+        }
+        return oXML;
+    }
+
+    public void setRes(String zSystem) {
+        _propStream = getClass().getResourceAsStream("/" + zSystem + ".properties");
+        try {
+            _props = new Properties();
+            _props.load(_propStream);
+            if (_props.containsKey("enc") && _props.getProperty("enc").equals("true")) {
+                _props = new EncryptedProperties();
+                _propStream = getClass().getResourceAsStream("/" + zSystem + ".properties");
+                _props.load(_propStream);
+            }
+        } catch (Exception ex) {
+            _propStream = null;
+        }
+    }
+
+    private Properties res() {
+        if (_propStream == null) {
+            setRes(zgSystem);
+        }
+        return _props;
+    }
+
+    public String getRes(String key) {
+        return getRes(key, null);
+    }
+
+    public String getRes(String key, String def) {
+        if (res().containsKey(key)) {
+            return res().getProperty(key);
+        }
+        return def;
+    }
+
+    public int getRes(String key, int def) {
+        if (res().containsKey(key)) {
+            return Integer.parseInt(res().getProperty(key));
+        }
+        return def;
+    }
+
+    public boolean getRes(String key, boolean def) {
+        if (res().containsKey(key)) {
+            String s = getRes(key, "").toLowerCase();
+            return s.startsWith("t") || s.startsWith("y");
+        }
+        return def;
+    }
+    /**
+     * From a password, a number of iterations and a salt, returns the
+     * corresponding digest
+     *
+     * @param iterationNb int The number of iterations of the algorithm
+     * @param password String The password to encrypt
+     * @param salt byte[] The salt
+     * @return byte[] The digested password
+     * @throws NoSuchAlgorithmException If the algorithm doesn't exist
+     */
+    public byte[] getHash(int iterationNb, String password, byte[] salt) throws Exception {
+        MessageDigest digest = MessageDigest.getInstance("SHA-1");
+        digest.reset();
+        digest.update(salt);
+        byte[] input = digest.digest(password.getBytes("UTF-8"));
+        for (int i = 0; i < iterationNb; i++) {
+            digest.reset();
+            input = digest.digest(input);
+        }
+        return input;
+    }
+
+    /**
+     * From a base 64 representation, returns the corresponding byte[]
+     *
+     * @param data String The base64 representation
+     * @return byte[]
+     * @throws IOException
+     */
+    public static byte[] base64ToByte(String data) throws IOException {
+        return Base64.decode(data);
+    }
+
+    /**
+     * From a byte[] returns a base 64 representation
+     *
+     * @param data byte[]
+     * @return String
+     * @throws IOException
+     */
+    public static String byteToBase64(byte[] data) {
+        return Base64.encode(data);
+    }
+
+    public static String HTMLEncode(String string) {
+        StringBuffer sb = new StringBuffer(string.length());
+        int len = string.length();
+        char c;
+
+        for (int i = 0; i < len; i++) {
+            c = string.charAt(i);
+
+            // HTML Special Chars
+            if (c == '"') {
+                sb.append("&quot;");
+            } else if (c == '&') {
+                sb.append("&amp;");
+            } else if (c == '<') {
+                sb.append("&lt;");
+            } else if (c == '>') {
+                sb.append("&gt;");
+            } else if (c == '\n') // Handle Newline
+            {
+                sb.append("&lt;br/&gt;");
+            } else {
+                int ci = 0xffff & c;
+                if (ci < 160) // nothing special only 7 Bit
+                {
+                    sb.append(c);
+                } else {
+                    // Not 7 Bit use the unicode system
+                    sb.append("&#");
+                    sb.append(Integer.toString(ci));
+                    sb.append(';');
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String HTMLDecode(String sHtml) {
+        int i;
+        String sTemp;
+        String[] vVar = sHtml.split("&");
+        StringBuilder Decoded = new StringBuilder();
+        Decoded.append(vVar[0]);
+        for (i = 1; i < vVar.length; i++) {
+            sTemp = vVar[i];
+            int iPos = sTemp.indexOf(";");
+            if (sTemp.length() > 1 && iPos != -1) {
+                String strEscape = sTemp.substring(0, sTemp.indexOf(";"));
+                if (strEscape.equals("lt")) {
+                    Decoded.append("<");
+                } else if (strEscape.equals("gt")) {
+                    Decoded.append(">");
+                } else if (strEscape.equals("amp") && sTemp.length() > iPos + 2 && sTemp.charAt(iPos + 1) == '#') {
+                    Decoded.append("&");
+                } else {
+                    Decoded.append("&" + strEscape + ";");
+                }
+
+                Decoded.append(sTemp.substring(iPos + 1));
+            } else {
+                Decoded.append("&" + sTemp);
+            }
+        }
+        return Decoded.toString();
+    }
+
+    public int pInt(String num) {
+        try {
+            return Integer.parseInt(num);
+        } catch (Exception ex) {
+            return 0;
+        }
+    }
+
+    public boolean isInt(String num) {
+        try {
+            Integer.parseInt(num);
+        } catch (Exception ex) {
+            return false;
+        }
+        return true;
+    }
+
+    public void log(String zMessage) {
+        log(Level.INFO, zMessage);
+    }
+
+    public void logError(String zMessage) {
+        log(Level.SEVERE, zMessage);
+    }
+
+    public void logError(Exception ex) {
+        log(Level.SEVERE, ex.getMessage());
+    }
+
+    public void log(Level level, String zMessage) {
+        String zClass = this.getClass().getName();
+        String zSuper = this.getClass().getSuperclass().getName();
+
+        StackTraceElement[] aST = Thread.currentThread().getStackTrace();
+        int i = 0;
+        for (i = 1; i < aST.length; i++) {
+            String c = aST[i].getClassName();
+            if (c.equals(zClass) || c.equals(zSuper)) {
+                break;
+            }
+        }
+//        if (level == Level.SEVERE)
+//        {
+//            try
+//            {
+//                //Send an email
+//                MailHelper oMail = new MailHelper();
+//                oMail.SendMail("paul@cloudsoft.co.uk", "paul@cloudsoft.co.uk", "Fatal Error - " + zMessage, Thread.currentThread().getStackTrace().toString());
+//            }
+//            catch (Exception ex)
+//            {}
+//        }
+        logger.logp(level, zClass, aST[i].getMethodName(), zMessage);
+    }
+
+    public String removeLeadingZeros(String s) {
+        return s.replaceFirst("^0*", "");
+    }
+
+    public String padLeft(String s, int n) {
+        s = String.format("%1$" + n + "s", s);
+        return (s.length() > n) ? s.substring(0, n) : s;
+    }
+
+    public String padRight(String s, int n) {
+        s = String.format("%1$-" + n + "s", s);
+        return (s.length() > n) ? s.substring(s.length() - n) : s;
+    }
+
+    public boolean isNullOrEmpty(String s) {
+        return (s == null || s.length() == 0);
+    }
+//    public String getRes(String zKey, String zDefault) {
+//        return getRes(zKey) == null ? zDefault : getRes(zKey);
+//    }
+//    public String getRes(String zKey) {
+//        String zVal = null;
+//        try {
+//            zVal = SystemResource().getString(zKey);
+//        } catch  (Exception ex) {}
+//        return zVal;
+//    }
+
+    public void exportResource(String resourceName, String OutputPath) throws Exception {
+        InputStream stream = null;
+        OutputStream resStreamOut = null;
+        try {
+            stream = getClass().getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree
+            if (resourceName.endsWith(".gz")) {
+                stream = new GZIPInputStream(stream);
+            }
+            if (stream == null) {
+                throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
+            }
+
+            int readBytes;
+            byte[] buffer = new byte[4096];
+            resStreamOut = new FileOutputStream(OutputPath);
+            while ((readBytes = stream.read(buffer)) > 0) {
+                resStreamOut.write(buffer, 0, readBytes);
+            }
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            stream.close();
+            resStreamOut.close();
+        }
+    }
+
+    protected double stats(String s) {
+        double ret = 0;
+        if (s.startsWith("start ")) {
+            s = s.substring(6);
+            oStats.put(s, new Date());
+        } else if (s.startsWith("end ") && oStats.containsKey(s.substring(4))) {
+            s = s.substring(4);
+            Date d = oStats.get(s);
+            double tDiff = new Date().getTime() - d.getTime();
+            oStats.remove(s);
+            System.out.print(dateTimeFormat.format(d) + "\t" + s + "\t");
+            ret = tDiff / 1000.00;
+            System.out.println(ret);
+        } else {
+            System.out.println(dateTimeFormat.format(new Date()) + "\t" + s);
+        }
+        return ret;
+    }
+
+    protected void statStart(String s) {
+        stats("start " + s);
+    }
+
+    protected double statEnd(String s) {
+        return stats("end " + s);
+    }
+
+}

+ 53 - 0
src/com/cloudsoft/utils/ExampleHttpSuper.java

@@ -0,0 +1,53 @@
+package com.cloudsoft.utils;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import javax.servlet.jsp.*;
+import java.io.*;
+
+/**
+ * An example of a superclass for an HTTP JSP class
+ */
+
+public abstract class ExampleHttpSuper implements HttpJspPage
+{
+     private ServletConfig config;
+
+final public void init(ServletConfig config) throws
+ServletException {
+     this.config = config;
+     jspInit();
+}
+final public ServletConfig getServletConfig() {
+     return config;
+}
+// This one is not final so it can be overridden
+// by a more precise method
+public String getServletInfo() {
+     return "A Superclass for an HTTP JSP"; // maybe better?
+}
+final public void destroy() {
+     jspDestroy();
+}
+
+/**
+* The entry point into service.
+*/
+
+final public void service(ServletRequest req, ServletResponse res)
+     throws ServletException, IOException
+{
+
+     // casting exceptions will be raised if an internal error.
+     HttpServletRequest request = (HttpServletRequest) req;
+     HttpServletResponse response = (HttpServletResponse) res;
+
+     _jspService(request, response);
+}
+/**
+* abstract method to be provided by the JSP processor in the subclass
+* Must be defined in subclass.
+*/
+abstract public void _jspService(HttpServletRequest request,
+     HttpServletResponse response) throws ServletException, IOException;
+
+}

+ 58 - 0
src/com/cloudsoft/utils/JARResourceResolver.java

@@ -0,0 +1,58 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import org.apache.xmlgraphics.io.Resource;
+import org.apache.xmlgraphics.io.ResourceResolver;
+
+/**
+ *
+ * @author paul
+ */
+public class JARResourceResolver implements ResourceResolver{
+    private String _base = null;
+
+    @Override
+    public Resource getResource(URI uri) throws IOException {
+        String scheme = uri.getScheme();
+        InputStream oStream = null;
+        if (scheme.equals("file")) {
+            if (_base == null) {
+                _base = System.getProperty("user.dir").replace('\\', '/') + "/";
+            }
+            String href = uri.getPath().replace(_base, "");                 
+            oStream = getClass().getResourceAsStream(href);
+            if (oStream == null) {
+                oStream = new FileInputStream(href);
+            }
+        } else {
+                oStream = uri.toURL().openStream();
+            }
+                return new Resource(oStream);
+//            _base = href.substring(0, href.lastIndexOf('/') + 1);
+//            href = href.substring(href.lastIndexOf('/') + 1);
+             
+//        System.out.println(uri);
+//        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public OutputStream getOutputStream(URI uri) throws IOException {
+        if (_base == null) {
+            String href = uri.toString(); 
+            _base = href.substring(0, href.lastIndexOf('/') + 1);
+            href = href.substring(href.lastIndexOf('/') + 1);
+        }        
+        System.out.println(uri);
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+    
+}

+ 50 - 0
src/com/cloudsoft/utils/JARURIResolver.java

@@ -0,0 +1,50 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import javax.xml.transform.Source;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamSource;
+
+/**
+ *
+ * @author pyl38997
+ */
+public class JARURIResolver implements URIResolver
+{
+    private String _base = null;
+    public JARURIResolver()
+    {
+    }
+    @Override
+    public Source resolve(String href, String base)
+    {
+        if (_base == null)
+        {
+            _base = href.substring(0, href.lastIndexOf('/') + 1);
+            href = href.substring(href.lastIndexOf('/') + 1);
+        }
+        InputStream oStream = null;
+        if (href.startsWith("http://")) {
+            try {
+                URL oURL = new URL(href); 
+                oStream = oURL.openStream();
+            } catch (Exception ex) {
+            }
+        } else {
+            oStream = getClass().getResourceAsStream(_base + href);
+        }
+        StreamSource oSource = null;
+        if (oStream == null)
+            oSource = new StreamSource(new File(_base + href));
+        else
+            oSource = new StreamSource(oStream);
+        return oSource;
+    }
+}

+ 118 - 0
src/com/cloudsoft/utils/LUHelper.java

@@ -0,0 +1,118 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author paul
+ */
+public class LUHelper
+{
+
+    private static XMLHelper _Lookups = null;
+    private static XMLHelper _Settings = null;
+    private static XMLHelper _Messages = null;
+
+    public static XMLHelper Lookups()
+    {
+        if (_Lookups == null)
+        {
+            try
+            {
+                //Get all codes form the database
+                DBHelper oDB = new DBHelper("CS");
+                String zSQL =
+                        "select lt.lookup_type_code as \"@type\", " 
+                        + "	lc.lookup_code_id	as \"@id\", " 
+                        + "	lc.code_type		as \"@code\", " 
+                        + "	lc.descr			as \"@descr\" " 
+                        + "from	uko_lookup_type lt,  " 
+                        + "	uko_lookup_code lc " 
+                        + "where   lc.lookup_type_id = lt.lookup_type_id " 
+                        + "and		lt.combo_flag = 'Y' " 
+                        + "and		lt.delete_user_id is null " 
+                        + "and		lc.delete_user_id is null " 
+                        + "order by lt.lookup_type_code, lc.seq_no";
+
+                _Lookups = oDB.getDOM(zSQL, 0, 9999999, false, "lookups", "lookup", false);
+            }
+            catch (Exception ex)
+            {
+            }
+        }
+        return _Lookups;
+    }
+
+    public static XMLHelper Settings()
+    {
+        if (_Settings == null)
+        {
+            try
+            {
+                //Get all codes form the database
+                DBHelper oDB = new DBHelper("CS");
+                String zSQL =
+                        "select	lc.lookup_code_id	as \"@id\", " 
+                        + "lc.code_type		as \"@code\", " 
+                        + "lc.descr			as \"@descr\" " 
+                        + "from	uko_lookup_type lt, " 
+                        + "uko_lookup_code lc " 
+                        + "where   lc.lookup_type_id = lt.lookup_type_id " 
+                        + "and		lt.lookup_type_code = 'settings' " 
+                        + "and		lt.delete_user_id is null " 
+                        + "and		lc.delete_user_id is null";
+
+                _Settings = oDB.getDOM(zSQL, 0, 9999999, false, null, "setting", false);
+            }
+            catch (Exception exception)
+            {
+            }
+        }
+        return _Settings;
+    }
+
+    public static XMLHelper Messages()
+    {
+        if (_Messages == null)
+        {
+            try
+            {
+                //Get all codes form the database
+                DBHelper oDB = new DBHelper("UKO");
+                String zSQL =
+                        "select	lc.lookup_code_id	as \"@id\", " 
+                        + "lc.code_type		as \"@code\", " 
+                        + "lc.descr			as \"@descr\" " 
+                        + "from	uko_lookup_type lt, " 
+                        + "uko_lookup_code lc " 
+                        + "where   lc.lookup_type_id = lt.lookup_type_id " 
+                        + "and		lt.lookup_type_code = 'sys_messages' " 
+                        + "and		lt.delete_user_id is null " 
+                        + "and		lc.delete_user_id is null";
+
+                _Messages = oDB.getDOM(zSQL, 0, 9999999, false, null, "message", false);
+            }
+            catch (Exception exception)
+            {
+            }
+        }
+        return _Messages;
+    }
+
+    public static String getValue(String code_type, String code)
+    {
+        return Lookups().getString("lookups/lookup[@type='" + code_type + "' and @code='" + code + "']/@descr");
+    }
+
+    public static String getSetting(String code)
+    {
+        return Settings().getString("setting[@code='" + code + "']/@descr");
+    }
+
+    public static String getMessage(String code)
+    {
+        return Messages().getString("message[@code='" + code + "']/@descr");
+    }
+}

+ 70 - 0
src/com/cloudsoft/utils/Log.java

@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.Writer;
+import java.util.Date;
+import java.util.Hashtable;
+
+/**
+ *
+ * @author Administrator
+ */
+public class Log 
+{
+    private Writer _out =  null;
+    private Hashtable<String, LogStats> _col = new Hashtable<String, LogStats>();
+    
+
+    public Log()
+    {
+        
+    }
+    
+    public Log(Writer out)
+    {
+        _out = out;
+    }
+    
+    public void logEnter(String zType)
+    {
+        LogStats oStats;
+        if (_col.containsKey(zType))
+            oStats = _col.get(zType);
+        else
+            oStats = new LogStats();
+        
+        oStats.StartTime = new Date().getTime();
+        oStats.Type = zType;
+        _col.put(zType, oStats);
+        
+    }
+    public void logExit(String zType)
+    {
+        if (_col.containsKey(zType))
+        {
+            LogStats oStats = _col.get(zType);
+            oStats.Duration += (new Date().getTime() - oStats.StartTime);
+            oStats.Calls++;
+        }
+    }
+    public void writeStats(Writer out)
+    {
+        _out = out;
+        writeStats();
+    }
+    public void writeStats()
+    {
+        for (LogStats oStats : _col.values() ) 
+        {
+            try
+            {
+                _out.write("<br/>" + oStats.Type + ": " + oStats.Calls + " calls, " + oStats.Duration + " duration, " + (oStats.Duration / oStats.Calls) + "average.\n");
+            }
+            catch (Exception ex){}
+        }
+    }
+    
+}

+ 17 - 0
src/com/cloudsoft/utils/LogStats.java

@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author Administrator
+ */
+public class LogStats
+{
+    public int Calls = 0;
+    public long Duration = 0;
+    public long StartTime = 0;
+    public String Type = "";
+}

+ 173 - 0
src/com/cloudsoft/utils/MailHelper.java

@@ -0,0 +1,173 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.InputStream;
+import java.util.Properties;
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.mail.Authenticator;
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.Multipart;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+/**
+ *
+ * @author pyl38997
+ */
+public class MailHelper 
+{
+    private String _From;
+    private String _To;
+    private String _Subject;
+    private String _SMTPServer = "localhost";
+    private String _AuthUser = null;
+    private String _AuthPassword = null;
+    private String _Port = null;
+
+    public MailHelper()
+    {
+        
+    }
+    public MailHelper(String smtpserver)
+    {
+        _SMTPServer = smtpserver;
+    }
+    public MailHelper(String zFrom, String zTo)
+    {
+        _From = zFrom;
+        _To  = zTo;
+    }
+    public MailHelper(String zFrom, String zTo, String zSubject)
+    {
+        _From = zFrom;
+        _To  = zTo;
+        _Subject = zSubject;
+        
+    }
+    public void setAuth(String authuser, String authpassword) {
+        _AuthUser = authuser;
+        _AuthPassword = authpassword;
+    }
+    private class SMTPAuthenticator extends javax.mail.Authenticator {
+        public PasswordAuthentication getPasswordAuthentication() {
+           String username = _AuthUser;
+           String password = _AuthPassword;
+           return new PasswordAuthentication(username, password);
+        }
+    } 
+    private Session getSMTPSession() {
+        Session session = null;
+        Properties props = new Properties();
+        props.put("mail.smtp.host", _SMTPServer);
+        if (_AuthUser != null){
+            props.put("mail.transport.protocol", "smtp");
+            props.put("mail.smtp.port", "587");
+            props.put("mail.smtp.auth", "true");
+            props.put("mail.smtp.starttls.enable","true");
+            Authenticator auth = new SMTPAuthenticator();
+            session = Session.getDefaultInstance(props, auth);
+        }
+        if (session == null) {
+            session = Session.getInstance(props);
+        }
+        return session;
+    }
+
+    public void SendMail(String zFrom, String zTo, String zSubject, String zMessage) throws Exception
+    {
+        Session session = getSMTPSession();
+        MimeMessage msg = new MimeMessage(session);
+        msg.setText(zMessage);
+        msg.setSubject(zSubject);
+        msg.setFrom(new InternetAddress(zFrom));
+        for (String to : zTo.split(";")) {
+            msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
+        }
+        Transport.send(msg);
+    }
+    public void SendMail(String zFrom, String zTo, String zSubject, String zHTML, boolean isHTML) throws Exception
+    {
+        //zTo = "pyl38997@gsk.com";
+        Session session = getSMTPSession();
+        MimeMessage msg = new MimeMessage(session);
+        
+        msg.setContent(zHTML, "text/html");
+        msg.setSubject(zSubject);
+        msg.setFrom(new InternetAddress(zFrom));
+        msg.addRecipient(Message.RecipientType.TO, new InternetAddress(zTo));
+        Transport.send(msg);
+    }
+    public void SendMail(String zFrom, String zTo, String zSubject, String zMessage, String zFilename) throws Exception
+    {
+        Session session = getSMTPSession();
+        MimeMessage msg = new MimeMessage(session);
+        msg.setSubject(zSubject);
+        msg.setFrom(new InternetAddress(zFrom));
+        msg.addRecipient(Message.RecipientType.TO, new InternetAddress(zTo));
+        msg.setSubject(zSubject);
+        msg.setFrom(new InternetAddress(zFrom));
+        msg.addRecipient(Message.RecipientType.TO, new InternetAddress(zTo));
+        BodyPart messageBodyPart = new MimeBodyPart();
+        messageBodyPart.setText(zMessage);
+        Multipart multipart = new MimeMultipart();
+        multipart.addBodyPart(messageBodyPart);
+
+        messageBodyPart = new MimeBodyPart();
+        DataSource source = new FileDataSource(zFilename);
+        messageBodyPart.setDataHandler(new DataHandler(source));
+        messageBodyPart.setFileName(zFilename.substring(zFilename.lastIndexOf('/')+1));
+        multipart.addBodyPart(messageBodyPart);
+        msg.setContent(multipart);
+        Transport.send(msg);
+    }
+    
+    public void SendMailPDF(String zFrom, String zTo, String zSubject, String zMessage, InputStream is, String zFilename) throws Exception
+    {
+        Session session = getSMTPSession();
+        MimeMessage msg = new MimeMessage(session);
+        msg.setSubject(zSubject);
+        msg.setFrom(new InternetAddress(zFrom));
+        for (String to : zTo.split(";")) {
+            msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
+        }
+        BodyPart messageBodyPart = new MimeBodyPart();
+        messageBodyPart.setText(zMessage);
+        Multipart multipart = new MimeMultipart();
+        multipart.addBodyPart(messageBodyPart);
+
+        messageBodyPart = new MimeBodyPart();
+        DataSource source = new ByteArrayDataSource(is, "application/pdf");
+        messageBodyPart.setDataHandler(new DataHandler(source));
+        messageBodyPart.setFileName(zFilename);
+        multipart.addBodyPart(messageBodyPart);
+        msg.setContent(multipart);
+        Transport.send(msg);
+    }
+
+    /**
+         * @param args the command line arguments
+         */
+        public static void main(String[] args) throws Exception
+        {
+//            MailHelper oMail = new MailHelper();
+//            XMLHelper oDOM = new XMLHelper("response");
+//            StringWriter oString = new StringWriter();
+//            oDOM.transform("/home/paul/java/ecommerce/vaccines.co.uk/web/xsl/order_email.xsl", oString);
+//            oMail.SendMail("paul@cloudsoft.co.uk", "pyl38997@gsk.com", "Order", oString.toString(), true);
+            MailHelper oMail = new MailHelper("sohomgsbisql01");
+//            oMail.setAuth("europe\\senrep", "$42HHttzmwWn=_5");
+            oMail.SendMail("p3busint@microsoft.com", "a-palise@microsoft.com", "Test5", "Test5");
+        }    
+}

+ 234 - 0
src/com/cloudsoft/utils/MortonList.java

@@ -0,0 +1,234 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.awt.Point;
+import java.util.Vector;
+
+//  **************************************************************************************************
+/** Stores a one-dimensional ordered list of objects that can represent a two-dimensional arrangement
+ *  using Morton ordering. The order of objects stored in this collection is assumed to be Morton. 
+ *  Ordering can be <code>VERTICAL</code> (mirror 'N' shaped) or <code>HORIZONTAL</code> ('Z' shaped).
+  * @author Jo Wood, giCentre.
+  * @version 3.0, 24th February, 2011.
+  * @param <E> Type of object stored in the Morton ordered collection. 
+  */ 
+//  **************************************************************************************************
+
+/* This file is part of the giCentre treeMappa library. treeMappa is free software: you can 
+ * redistribute it and/or modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ * 
+ * treeMappa is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+ * See the GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License along with this
+ * source code (see COPYING.LESSER included with this source code). If not, see 
+ * http://www.gnu.org/licenses/.
+ */
+
+public class MortonList<E> extends Vector<E>
+{
+        // -------------------- Object and class variables -------------------
+        
+        private static final long serialVersionUID = 1464385625231719807L;
+        
+                                                        /** Indicates that Morton ordering is mirror 'N' shaped. */
+        public static final int VERTICAL = 1;
+                                                        /** Indicates that Morton ordering is 'Z' shaped. */
+        public static final int HORIZONTAL = 2; 
+        
+        private int direction;
+        
+
+        // --------------------------- Constructor ---------------------------
+        
+        /** Creates the collection assuming a vertical Morton layout.
+          */
+        public MortonList()
+        {
+                this(VERTICAL);
+                
+        }
+        
+        /** Creates the collection with a Morton layout in the given direction.
+          * @param direction Direction of layout. Should be one of <code>VERTICAL</code>
+          * (mirrored 'N' shaped) or <code>HORIZONTAL</code> ('Z' shaped). 
+          */
+        public MortonList(int direction)
+        {
+                super();
+                this.direction = direction;
+        }
+
+        // ----------------------------- Methods -----------------------------
+        
+        /** Clears this collection and sets the given direction for Morton ordering.
+          * @param mDirection New direction for Morton ordering. Should be one of <code>VERTICAL</code>
+          * (mirrored 'N' shaped) or <code>HORIZONTAL</code> ('Z' shaped). 
+          */
+        public void resetDirection(int mDirection)
+        {
+                clear();
+                this.direction = mDirection;
+        }
+        
+        /** Returns the x,y position of the first occurrence of the given object in this collection,
+          * or null if the collection does not contain the object.
+          * @param obj Object whose position will be reported.
+          * @return 2-dimensional position of the object.
+          */
+        public Point positionOf(Object obj)
+        {
+                int index = indexOf(obj);
+                if (index < 0)
+                {
+                        return null;
+                }
+                
+                return new Point(getX(index),getY(index));      
+        }
+        
+        
+        /** Returns the object at the given x,y position or null if no object at the given position.
+          * Note that it is not possible to distinguish between a null object at a given position
+          * and position that it out of bounds of the current collection.
+          * @param x x coordinate of the position from which to retrieve the object.
+          * @param y x coordinate of the position from which to retrieve the object. 
+          * @return Object at the given position or null if out of bounds or no object.
+          */
+        public E get(int x, int y)
+        {
+                int morton = getMorton(x, y);
+                if (morton >= size())
+                {
+//System.err.println("Position out of bounds: Morton number for "+x+","+y+" is "+morton+" but collection only has "+size()+" elements.");                       
+                        return null;
+                }
+                
+                return get(morton);
+        }
+        
+        /** Returns the object that is to the 'right' (x+1) of the first instance of the given reference object
+          * or null if no object to the right or if the given reference object not found. 
+          * @param obj Reference object from which to find its neighbour.
+          * @return Object to the right of the given reference object.
+          */
+        public E getNextX(Object obj)
+        {
+                Point position = positionOf(obj);
+                
+                if (position == null)
+                {
+//System.err.println("getNextX(): Object "+obj+" not found in collection.");                    
+                        return null;
+                }
+                return get(position.x+1,position.y);
+        }
+        
+        
+        /** Returns the object that is 'below' (y+1) the first instance of the given reference object
+          * or null if no object below or if the given reference object not found. 
+          * @param obj Reference object from which to find its neighbour.
+          * @return Object below the given reference object.
+          */
+        public E getNextY(Object obj)
+        {
+                Point position = positionOf(obj);
+                
+                if (position == null)
+                {
+//System.err.println("getNextY(): Object "+obj+" not found in collection.");                    
+                        return null;
+                }
+                return get(position.x,position.y+1);
+        }
+                        
+        /** Reports the x coordinate of the position represented by the given Morton number.
+          * @param mortonNumber Number to process.
+          * @return x coordinate represented by the Morton number.
+          */
+        public int getX(int mortonNumber)
+        {
+                int x=0;
+                
+                if (direction == HORIZONTAL)
+                {
+                        for (int i=0; i<32; i+=2)
+                        {
+                                int mask = 1 << (i);
+                                x += (mortonNumber&mask)>>(i/2);
+                        }
+                }
+                else
+                {
+                        for (int i=1; i<32; i+=2)
+                        {
+                                int mask = 1 << (i);
+                                x += (mortonNumber&mask)>>((i+1)/2);
+                        }
+                }
+                
+                return x;
+        }
+        
+        /** Reports the y coordinate of the position represented by the given Morton number.
+          * @param mortonNumber Number to process.
+          * @return y coordinate represented by the Morton number.
+          */
+        public int getY(int mortonNumber)
+        {
+                int y=0;
+                
+                if (direction == HORIZONTAL)
+                {
+                        for (int i=1; i<32; i+=2)
+                        {
+                                int mask = 1 << (i);
+                                y += (mortonNumber&mask)>>((i+1)/2);
+                        }
+                }
+                else
+                {
+                        for (int i=0; i<32; i+=2)
+                        {
+                                int mask = 1 << (i);
+                                y += (mortonNumber&mask)>>(i/2);
+                        }
+                }
+                
+                return y;
+        }
+        
+        /** Reports the Morton number representing the given x,y coordinate pair.
+          * @param x x coordinate of position to calculate.
+          * @param y y coordinate of position to calculate.
+          * @return Morton number representing the given position. 
+          */
+        public int getMorton(int x, int y)
+        {
+                int newX = x;
+                int newY = y;
+                int morton = 0;
+                
+                if (direction == HORIZONTAL)
+                {
+                        // Swap x and y coordinates for horizontal ordering.
+                        newX = y;
+                        newY = x;
+                }
+                
+                for (int i=0; i<16; i++)
+                {
+                        int mask = 1 << (i);
+                        morton += (newX&mask)<<(i+1);
+                        morton += (newY&mask)<<i;
+                }       
+                return morton;
+        }
+}
+

+ 153 - 0
src/com/cloudsoft/utils/Pictures.java

@@ -0,0 +1,153 @@
+/*
+ * Pictures.java
+ *
+ * Created on 08 March 2007, 10:28
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+import java.io.*;
+
+/**
+ *
+ * @author pyl38997
+ */
+public class Pictures
+{
+    
+    /** Creates a new instance of Pictures */
+    public Pictures()
+    {
+    }
+    
+    
+    public void runCommand(String sCommand)
+    {
+        String s = null;
+        
+        try
+        {
+            
+            // run the Unix command
+            Process p = Runtime.getRuntime().exec(sCommand);
+            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+            
+            // read the output from the command
+            System.out.println("Here is the standard output of the command:\n");
+            while ((s = stdInput.readLine()) != null)
+            {
+                System.out.println(s);
+            }
+            
+            // read any errors from the attempted command
+            System.out.println("Here is the standard error of the command (if any):\n");
+            while ((s = stdError.readLine()) != null)
+            {
+                System.out.println(s);
+            }
+        }
+        catch (IOException e)
+        {
+            System.out.println("exception happened - here's what I know: ");
+            e.printStackTrace();
+            System.exit(-1);
+        }
+        
+    }
+    
+    public File[] getDirs(String sPath)
+    {
+        File dir = new File(sPath);
+        
+        // This filter only returns directories
+        FileFilter fileFilter = new FileFilter()
+        {
+            public boolean accept(File file)
+            {
+                return file.isDirectory();
+            }
+        };
+        return dir.listFiles(fileFilter);
+    }
+    
+    public File[] getPics(String sPath)
+    {
+        
+        File dir = new File(sPath);
+        
+        // This filter only returns directories
+        FileFilter fileFilter = new FileFilter()
+        {
+            public boolean accept(File file)
+            {
+                return file.getName().endsWith(".jpg");
+            }
+        };
+        return dir.listFiles(fileFilter);
+        
+    }
+    
+    public boolean fileExists(String sPath)
+    {
+        return new File(sPath).exists();
+    }
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args)
+    {
+        Pictures pics = new Pictures();
+        String sMainDir = "/Users/paul/hodgeimaging";
+        File[] dirs = pics.getDirs(sMainDir);
+        XMLHelper oXML = new XMLHelper("categories");
+        
+        for (int i=0; i < dirs.length; i++)
+        {
+            String sOrigDir = dirs[i].getPath() + "/original";
+            String sNewDir = dirs[i].getPath() + "/sized";
+            String sTNDir = dirs[i].getPath() + "/tn";
+            XMLHelper oCat = oXML.appendNode("category");
+            oCat.appendAttribute("path", dirs[i].getPath());
+            oCat.appendAttribute("name", dirs[i].getName());
+            if (!pics.fileExists(sNewDir))
+                pics.runCommand("mkdir " + sNewDir);
+            
+            if (!pics.fileExists(sTNDir))
+                pics.runCommand("mkdir " + sTNDir);
+            
+            File[] aPics = pics.getPics(sOrigDir);
+            XMLHelper oPics = oCat.appendNode("pics");
+            
+            for (int j=0; aPics != null && j < aPics.length; j++)
+            {
+                String sOrig = aPics[j].getPath();
+                String sNew = sNewDir + "/" + aPics[j].getName();
+                String sCmd = "/opt/local/bin/convert " + sOrig.replace(" ", "\"") + " -resize 700 " + sNew.replace(" ", "\"");
+                pics.runCommand(sCmd);
+                String sTN = sTNDir + "/" + aPics[j].getName();
+                sCmd = "/opt/local/bin/convert " + sOrig.replace(" ", "\"") + " -resize 100 " + sTN.replace(" ", "\"");
+                pics.runCommand(sCmd);
+                sCmd = "/opt/local/bin/composite -watermark 13.0 " + sMainDir + "/phootoowm.gif " + sNew.replace(" ", "\"") + " " + sNew.replace(" ", "\"");
+                pics.runCommand(sCmd);
+                oPics.appendNode("pic").appendAttribute("name", aPics[j].getName());
+            }
+        }
+        System.out.println(oXML.getXML());
+        try
+        {
+            
+            FileWriter oFW = new FileWriter(sMainDir + "/pics.xml");
+            oXML.serializeNode(oFW);
+            oFW.close();
+        }
+        catch (IOException ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+    
+    
+}

+ 124 - 0
src/com/cloudsoft/utils/PropertiesTask.java

@@ -0,0 +1,124 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ *
+ * @author paul
+ */
+public class PropertiesTask extends Task {
+
+    private File outputFolder;
+    private String outputFile;
+    private List inputFileSet = new ArrayList();
+    private String outputSuffix = ".properties";
+
+    /**
+     *
+     */
+    public PropertiesTask() {
+        super();
+    }
+
+    /**
+     * @return the outputFolder
+     */
+    public File getOutputFolder() {
+        return outputFolder;
+    }
+
+    /**
+     * @param outputFolder the outputFolder to set
+     */
+    public void setOutputFolder(File outputFolder) {
+        this.outputFolder = outputFolder;
+    }
+
+    public void addFileset(FileSet fileset) {
+        inputFileSet.add(fileset);
+    }
+
+    public void setOutputFile(String outputFile) {
+        this.outputFile = outputFile;
+    }
+    /**
+     * @see org.apache.tools.ant.Task#execute()
+     */
+    public void execute() throws BuildException {
+        for (Iterator iter = inputFileSet.iterator(); iter.hasNext();) {
+            FileSet fs = (FileSet) iter.next();
+            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+            File base = ds.getBasedir();
+            String[] includedFiles = ds.getIncludedFiles();
+            for (int i = 0; i < includedFiles.length; i++) {
+                includedFiles[i] = includedFiles[i].replace('\\', '/');
+
+                String includePrefix = "";
+                if (includedFiles[i].lastIndexOf('/') != -1) {
+                    includePrefix = includedFiles[i].substring(0, includedFiles[i].lastIndexOf('/'));
+                }
+                File found = new File(base, includedFiles[i]);
+                File targetFolder = null;
+                if (includePrefix.length() > 0) {
+                    targetFolder = new File(outputFolder, includePrefix);
+                } else {
+                    targetFolder = new File(outputFolder.getAbsolutePath());
+                }
+                targetFolder.mkdirs();
+                File outFile = null;
+                System.out.println(includedFiles[i] + ":" + targetFolder.getAbsolutePath());
+                String theFileName = (outputFile == null) ? found.getName() : outputFile;
+                int lastIndex = theFileName.lastIndexOf(".");
+
+                outFile = new File(targetFolder, theFileName);
+
+                try {
+                    doEncryption(found, outFile);
+                } catch (Exception e) {
+                    log("Error compressing " + found.getAbsolutePath() + ", " + e.getMessage());
+                    throw new BuildException("Error compressing " + found.getAbsolutePath() + ", " + e.getMessage(), e);
+                }
+            }
+        }
+    }
+
+    /**
+     * @param string
+     * @param outputFile
+     */
+    private void doEncryption(File inputFile, File outputFile)
+            throws Exception {
+        log("Encypting " + inputFile.getAbsolutePath() + " to " + outputFile.getAbsolutePath());
+        FileInputStream is = null;
+        FileOutputStream os = null;
+        outputFile.getParentFile().mkdirs();
+        if (inputFile.getName().endsWith(outputSuffix)) {
+            Properties prop = new Properties();
+            is = new FileInputStream(inputFile);
+            prop.load(is);
+            EncryptedProperties encprop = new EncryptedProperties();
+            encprop.setProperty("enc", "true", false);
+            for (Object key : prop.keySet()) {
+                encprop.setProperty((String) key, (String) prop.get(key));
+            }
+            os = new FileOutputStream(outputFile);
+            encprop.store(os, "Encrypted Properties file");
+        }
+    }
+
+}

+ 109 - 0
src/com/cloudsoft/utils/RegHelper.java

@@ -0,0 +1,109 @@
+package com.cloudsoft.utils;
+
+import java.lang.reflect.Method;
+import java.util.prefs.Preferences;
+
+public class RegHelper
+{
+  /* Windows hives */
+  private static final int HKEY_CURRENT_USER = 0x80000001;
+  private static final int HKEY_LOCAL_MACHINE = 0x80000002;
+
+  /* Windows security masks */
+  private static final int KEY_READ = 0x20019;
+
+  /* Constants used to interpret returns of native functions */
+  private static final int NATIVE_HANDLE = 0;
+  private static final int ERROR_CODE = 1;
+
+  /* Windows error codes. */
+  private static final int ERROR_SUCCESS = 0;
+
+  public static String getKeySz(String keyName, String valueName, String valueDefault)
+  {
+    int hive = HKEY_LOCAL_MACHINE;
+
+    final Class<?> clazz = Preferences.userRoot().getClass();
+
+    try {
+      final Method openKeyMethod = clazz.getDeclaredMethod("WindowsRegOpenKey", int.class, byte[].class, int.class);
+      openKeyMethod.setAccessible(true);
+
+      final Method closeKeyMethod = clazz.getDeclaredMethod("WindowsRegCloseKey", int.class);
+      closeKeyMethod.setAccessible(true);
+
+      final Method queryValueMethod = clazz.getDeclaredMethod("WindowsRegQueryValueEx", int.class, byte[].class);
+      queryValueMethod.setAccessible(true);
+
+      int[] result = (int[]) openKeyMethod.invoke(null, hive, stringToByteArray(keyName), KEY_READ);
+      if (result[ERROR_CODE] != ERROR_SUCCESS)
+        return valueDefault;
+
+      int hKey = result[NATIVE_HANDLE];
+
+      byte[] b = (byte[]) queryValueMethod.invoke(null, hKey, stringToByteArray(valueName));
+      closeKeyMethod.invoke(null, hKey);
+
+      if (b == null)
+        return null;
+      else
+        return byteArrayToString(b);
+    }
+    catch (Exception e) {
+      return valueDefault;
+    }
+  }
+
+  /**
+   * Returns this java string as a null-terminated byte array
+   *
+   * @param str The string to convert
+   * @return The resulting null-terminated byte array
+   */
+  private static byte[] stringToByteArray(String str)
+  {
+    byte[] result = new byte[str.length() + 1];
+    for (int i = 0; i < str.length(); i++) {
+      result[i] = (byte) str.charAt(i);
+    }
+    result[str.length()] = 0;
+    return result;
+  }
+
+  /**
+   * Converts a null-terminated byte array to java string
+   *
+   * @param array The null-terminated byte array to convert
+   * @return The resulting string
+   */
+  private static String byteArrayToString(byte[] array)
+  {
+    StringBuilder result = new StringBuilder();
+    for (int i = 0; i < array.length - 1; i++) {
+      result.append((char) array[i]);
+    }
+    return result.toString();
+  }
+
+  //@SuppressWarnings({"UseOfSystemOutOrSystemErr", "HardcodedFileSeparator"})
+  private static void testKey(String keyName, String valueName)
+  {
+    String s;
+
+    System.out.print("HKLM\\");
+    System.out.println(keyName);
+    System.out.println("  Reading: " + valueName);
+
+      s = getKeySz(keyName, valueName, "---ERROR---");
+      System.out.println("    >>" + s + "<<");
+  }
+
+  //@SuppressWarnings({"HardcodedFileSeparator", "DuplicateStringLiteralInspection"})
+  public static void main(String args[])
+  {
+    testKey("SOFTWARE\\GlaxoWellcome\\IN", "DBSource");
+    testKey("SOFTWARE\\Valve\\Steam\\Apps\\15660", "");
+    testKey("SOFTWARE\\Valve\\Steam\\Apps\\22000", "");
+    testKey("SOFTWARE\\Valve\\Steam\\Apps\\22010", "");
+  }
+}

+ 132 - 0
src/com/cloudsoft/utils/ResourceList.java

@@ -0,0 +1,132 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+/**
+ * list resources available from the classpath @ *
+ */
+public class ResourceList{
+
+    /**
+     * for all elements of java.class.path get a Collection of resources Pattern
+     * pattern = Pattern.compile(".*"); gets all resources
+     * 
+     * @param pattern
+     *            the pattern to match
+     * @return the resources in the order they are found
+     */
+    public Collection<String> getResources(final Pattern pattern) throws Exception {
+        final ArrayList<String> retval = new ArrayList<String>();
+        final String classPath = System.getProperty("java.class.path", ".");
+        final String[] classPathElements = classPath.split(System.getProperty("path.separator"));
+        for(final String element : classPathElements){
+            retval.addAll(getResources(element, pattern));
+        }
+//        Enumeration<URL> urls = getClass().getClassLoader().getResources("/");
+//        while (urls.hasMoreElements()) {
+//            URL url = urls.nextElement();
+//            retval.addAll(getResources(url.getPath(), pattern));
+//        }
+        return retval;
+    }
+
+    private Collection<String> getResources(
+        final String element,
+        final Pattern pattern){
+        final ArrayList<String> retval = new ArrayList<String>();
+        final File file = new File(element);
+        if(file.isDirectory()){
+            retval.addAll(getResourcesFromDirectory(file, pattern));
+        } else{
+            retval.addAll(getResourcesFromJarFile(file, pattern));
+        }
+        return retval;
+    }
+
+    private Collection<String> getResourcesFromJarFile(
+        final File file,
+        final Pattern pattern){
+        final ArrayList<String> retval = new ArrayList<String>();
+        ZipFile zf;
+        try{
+            zf = new ZipFile(file);
+        } catch(final ZipException e){
+            throw new Error(e);
+        } catch(final IOException e){
+            throw new Error(e);
+        }
+        final Enumeration e = zf.entries();
+        while(e.hasMoreElements()){
+            final ZipEntry ze = (ZipEntry) e.nextElement();
+            final String fileName = ze.getName();
+            final boolean accept = pattern.matcher(fileName).matches();
+            if(accept){
+                retval.add(fileName);
+            }
+        }
+        try{
+            zf.close();
+        } catch(final IOException e1){
+            throw new Error(e1);
+        }
+        return retval;
+    }
+
+    private Collection<String> getResourcesFromDirectory(
+        final File directory,
+        final Pattern pattern){
+        final ArrayList<String> retval = new ArrayList<String>();
+        final File[] fileList = directory.listFiles();
+        for(final File file : fileList){
+            if(file.isDirectory()){
+                retval.addAll(getResourcesFromDirectory(file, pattern));
+            } else{
+                try{
+                    final String fileName = file.getCanonicalPath();
+                    final boolean accept = pattern.matcher(fileName).matches();
+                    if(accept){
+                        retval.add(fileName);
+                    }
+                } catch(final IOException e){
+                    throw new Error(e);
+                }
+            }
+        }
+        return retval;
+    }
+
+    /**
+     * list the resources that match args[0]
+     * 
+     * @param args
+     *            args[0] is the pattern to match, or list all resources if
+     *            there are no args
+     */
+    public static void main(final String[] args) throws Exception{
+        Pattern pattern;
+        if(args.length < 1){
+            pattern = Pattern.compile("^.*\\.properties$");
+        } else{
+            pattern = Pattern.compile(args[0]);
+        }
+        ResourceList rl = new ResourceList();
+        Collection<String> list = rl.getResources(pattern);
+        for(final String name : list){
+            System.out.println(name);
+        }
+    }
+}  

+ 92 - 0
src/com/cloudsoft/utils/SAXLoadHandler.java

@@ -0,0 +1,92 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author paul
+ */
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class SAXLoadHandler extends DefaultHandler {
+    SAXLoadInterface callback;
+	XMLHelper oDOM = new XMLHelper();
+        XMLHelper oCurrent = null;
+//        XMLHelper oMeta = null;
+        int iRow = 0;
+        int iMaxRows = 500; 
+        StringBuilder zNodeString = new StringBuilder();
+        String gSystem = "VE";
+        public SAXLoadHandler(SAXLoadInterface li) {
+            callback = li;
+        }
+        public SAXLoadHandler(SAXLoadInterface li, String zSystem) {
+            callback = li;
+            gSystem = zSystem;
+        }
+        public SAXLoadHandler(SAXLoadInterface li, String zSystem, int rows) {
+            callback = li;
+            gSystem = zSystem;
+            iRow = rows;
+        }
+	@Override
+        public void startElement(String uri, String localName,String qName, 
+                Attributes attributes) throws SAXException {
+                if (oCurrent == null) {
+                    oDOM.createRoot(qName);
+                    oCurrent = oDOM;
+                }
+                if (qName.equals("row")) {
+                    if (iRow % iMaxRows == 0) { 
+                        if (iRow > 0) {
+                            callback.setRows(oDOM);
+                        }
+                        oDOM = new XMLHelper();
+                        oDOM.createStandardRequest("load", "1", gSystem);
+                        oCurrent = oDOM.appendNode("rows");
+                    }
+                    iRow ++;
+                }
+                oCurrent = oCurrent.appendNode(qName);
+                int iLen = attributes.getLength();
+                for (int i=0; i < iLen; i++) {
+                    oCurrent.appendAttribute(attributes.getQName(i), attributes.getValue(i));
+                }
+	}
+ 
+	@Override
+	public void endElement(String uri, String localName,
+		String qName) throws SAXException {
+ 
+            if (qName.equals("meta_data")) {
+                callback.setColumns(oCurrent.getNodes("columns/column"));
+//                if (oMeta == null) {
+//                    oMeta = oCurrent;
+//                }
+            }
+            if (zNodeString.length() > 0) {
+                oCurrent.setNode(".", zNodeString.toString());
+                zNodeString = new StringBuilder();
+            }
+		oCurrent = oCurrent.getParent();
+ 
+	}
+ 
+	@Override
+	public void characters(char ch[], int start, int length) throws SAXException {
+                zNodeString.append(ch, start, length);
+ 
+	}
+
+	@Override
+        public void endDocument() {
+            callback.setRows(oDOM);
+            callback.loadComplete(iRow);
+        }
+    
+}

+ 17 - 0
src/com/cloudsoft/utils/SAXLoadInterface.java

@@ -0,0 +1,17 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author paul
+ */
+public interface SAXLoadInterface {
+    public void setColumns(XMLHelper[] columns);
+    public void setRows(XMLHelper oDOM);
+    public void loadComplete(int iRows);
+    
+}

+ 331 - 0
src/com/cloudsoft/utils/SCPHelper.java

@@ -0,0 +1,331 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.ChannelSftp;
+import java.util.Properties;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+/**
+ *
+ * @author paul
+ */
+public class SCPHelper
+{
+    private Session session = null;
+
+    public SCPHelper(String zUser, String zServer, String zKey, int iPort) throws Exception
+    {
+        JSch jsch = new JSch();
+        final byte[] emptyPassPhrase = new byte[0];
+
+        InputStream is = getClass().getResourceAsStream(zKey);
+        byte[] prvkey = new byte[is.available()];
+        is.read(prvkey);
+        jsch.addIdentity(zUser, prvkey, null, emptyPassPhrase);
+        session = jsch.getSession(zUser, zServer, iPort);
+        Properties properties = new Properties();
+        properties.put("StrictHostKeyChecking", "no");
+        session.setConfig(properties);
+
+        session.connect();
+    }
+
+    public SCPHelper(String zUser, String zServer, String zKey, String zPassword, int iPort) throws Exception
+    {
+        JSch jsch = new JSch();
+        final byte[] emptyPassPhrase = new byte[0];
+
+        InputStream is = getClass().getResourceAsStream(zKey);
+        byte[] prvkey = new byte[is.available()];
+        is.read(prvkey);
+        jsch.addIdentity(zUser, prvkey, null, emptyPassPhrase);
+        session = jsch.getSession(zUser, zServer, iPort);
+        session.setPassword(zPassword);
+        Properties properties = new Properties();
+        properties.put("StrictHostKeyChecking", "no");
+        session.setConfig(properties);
+
+        session.connect();
+    }
+    public ChannelSftp getSFTP() throws Exception
+    {
+        Channel channel = session.openChannel("sftp");
+        channel.connect();
+        ChannelSftp c = (ChannelSftp)channel;
+        return c;
+    }
+    
+    public int execCommand(String command, PrintStream ps) throws Exception
+    {
+        StringBuilder sb = new StringBuilder();
+        ChannelExec channel = (ChannelExec)session.openChannel("exec");
+        InputStream is = channel.getInputStream();
+        channel.setCommand(command);
+        channel.connect();
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        String line;
+        while ((line = reader.readLine()) != null) {
+            if (ps != null) {
+                ps.println(line);
+            }
+        }
+        int ExitStatus = channel.getExitStatus();
+        channel.disconnect();
+        return ExitStatus;
+    }
+    public void disconnect() {
+        session.disconnect();
+    }
+public byte[] scp(String zFrom) throws Exception
+{
+    ChannelExec c = (ChannelExec) session.openChannel("exec");
+    c.setCommand("scp -f " + zFrom);
+    OutputStream os = c.getOutputStream();
+    InputStream is = c.getInputStream();
+    c.connect();
+    os.write(0);
+    os.flush();
+    String header = readLine(is);
+    int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
+    os.write(0);
+    os.flush();
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    byte[] buffer = new byte[1024];
+    int bl = 0;
+    while (true)
+    {
+        if (buffer.length < length)
+            bl = buffer.length;
+        else
+            bl = length;
+        bl = is.read(buffer, 0, bl);
+        if (bl <= 0)
+            break;
+        out.write(buffer, 0, bl);
+        length -= bl;
+        if (length == 0)
+            break;
+    }
+    out.close();
+    if (is.read() != 0)
+      throw new Exception("SCP Ack check failed");
+    os.write(0);
+    os.flush();
+
+    c.disconnect();
+    return out.toByteArray();
+}
+public void scp(byte[] oOut, String zTo) throws Exception
+{
+      // exec 'scp -t rfile' remotely
+      String command = "scp -t " + zTo;
+      Channel channel = session.openChannel("exec");
+      ((ChannelExec)channel).setCommand(command);
+
+      // get I/O streams for remote scp
+      OutputStream out = channel.getOutputStream();
+      InputStream in = channel.getInputStream();
+
+      channel.connect();
+
+      if (checkAck(in) != 0)
+	throw new Exception("SCP Ack check failed");
+      // send "C0644 filesize filename", where filename should not include '/'
+      long filesize = oOut.length;
+      command="C0644 " + filesize + " ";
+      if (zTo.lastIndexOf('/') > 0)
+      {
+        command += zTo.substring(zTo.lastIndexOf('/')+1);
+      }
+      else
+      {
+        command += zTo;
+      }
+      command += "\n";
+      out.write(command.getBytes());
+      out.flush();
+      if(checkAck(in)!=0)
+      {
+        throw new Exception("SCP Ack check failed");
+      }
+
+      // send a content of The byte Array
+      out.write(oOut);
+      //oOut = null;
+      // send '\0'
+      out.write(0);
+      out.flush();
+      if(checkAck(in)!=0)
+      {
+        throw new Exception("SCP Ack check failed");
+      }
+      out.close();
+
+      channel.disconnect();
+}
+
+public void scp(String zFrom, String zTo) throws Exception
+{
+    FileInputStream fis=null;
+    try{
+
+      String lfile=zFrom;
+      String rfile=zTo;
+
+
+      boolean ptimestamp = true;
+
+      // exec 'scp -t rfile' remotely
+      String command = "scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
+      Channel channel = session.openChannel("exec");
+      ((ChannelExec)channel).setCommand(command);
+
+      // get I/O streams for remote scp
+      OutputStream out=channel.getOutputStream();
+      InputStream in=channel.getInputStream();
+
+      channel.connect();
+
+      if(checkAck(in)!=0)
+      {
+	throw new Exception("SCP Ack check failed");
+      }
+
+      File _lfile = new File(lfile);
+
+      if(ptimestamp){
+        command="T "+(_lfile.lastModified()/1000)+" 0";
+        // The access time should be sent here,
+        // but it is not accessible with JavaAPI ;-<
+        command+=(" "+(_lfile.lastModified()/1000)+" 0\n");
+        out.write(command.getBytes()); out.flush();
+        if(checkAck(in)!=0)
+        {
+            throw new Exception("SCP Ack check failed");
+        }
+      }
+
+      // send "C0644 filesize filename", where filename should not include '/'
+      long filesize=_lfile.length();
+      command="C0644 "+filesize+" ";
+      if(lfile.lastIndexOf('/')>0){
+        command+=lfile.substring(lfile.lastIndexOf('/')+1);
+      }
+      else{
+        command+=lfile;
+      }
+      command+="\n";
+      out.write(command.getBytes()); out.flush();
+      if(checkAck(in)!=0)
+      {
+        throw new Exception("SCP Ack check failed");
+      }
+
+      // send a content of lfile
+      fis=new FileInputStream(lfile);
+      byte[] buf=new byte[4096];
+      while(true){
+        int len=fis.read(buf, 0, buf.length);
+	if(len<=0) break;
+        out.write(buf, 0, len); //out.flush();
+      }
+      fis.close();
+      fis=null;
+      // send '\0'
+      buf[0]=0; out.write(buf, 0, 1); out.flush();
+      if(checkAck(in)!=0)
+      {
+        throw new Exception("SCP Ack check failed");
+      }
+      out.close();
+
+      channel.disconnect();
+      //session.disconnect();
+
+      //System.exit(0);
+    }
+    catch(Exception e){
+      try{if(fis!=null)fis.close();}catch(Exception ee){}
+      throw e;
+    }
+  }
+
+private String readLine(InputStream in) throws IOException
+{
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    for (;;) {
+        int c = in.read();
+        if (c == '\n') {
+            return baos.toString();
+        } else if (c == -1) {
+            throw new IOException("End of stream");
+        } else {
+            baos.write(c);
+        }
+    }
+}
+static int checkAck(InputStream in) throws IOException{
+    int b=in.read();
+    // b may be 0 for success,
+    //          1 for error,
+    //          2 for fatal error,
+    //          -1
+    if(b==0) return b;
+    if(b==-1) return b;
+
+    if(b==1 || b==2){
+      StringBuilder sb=new StringBuilder();
+      int c;
+      do
+      {
+	c=in.read();
+	sb.append((char)c);
+      }
+      while(c!='\n');
+
+      if(b==1){ // error
+	System.out.print(sb.toString());
+      }
+      if(b==2){ // fatal error
+	System.out.print(sb.toString());
+      }
+    }
+    return b;
+  }
+
+  public void close()
+  {
+      session.disconnect();
+  }
+    public static void main(String args[]) {
+        try {
+            SCPHelper test = new SCPHelper("paul", "www.nevershuts.com", "id_dsa", 222);
+            test.scp("c:/sw/vncviewer.exe", ".");
+            test.scp("c:/sw/vncviewer1.exe", ".");
+            test.scp("c:/sw/vncviewer2.exe", ".");
+            test.scp("c:/sw/netbeans.exe", ".");
+            test.close();
+        } catch (Exception ex) {
+            Logger.getLogger(SCPHelper.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+}

+ 135 - 0
src/com/cloudsoft/utils/ScopeBase.java

@@ -0,0 +1,135 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ *
+ * @author a-palise
+ */
+public class ScopeBase extends ErrHelper {
+    private final HashMap<String, Date> oStats = new HashMap<>();
+    private final DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private final String SCOPE_EXE = "C:\\ScopeSDK\\scope.exe";
+
+    /** Test Harness
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) throws Exception {
+                
+    }
+    protected int execScope(String args) throws Exception {
+        int iStatus = 0;
+        do {
+            if (iStatus != 0) {
+                log(args + " failed. Retrying...");
+            }
+            Process p = Runtime.getRuntime().exec(SCOPE_EXE + " " + args);
+            BufferedReader sr = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String line = null;
+            while ((line = sr.readLine()) != null) {
+//                System.out.println(line);
+            }
+            sr.close();
+            iStatus = p.exitValue();
+        } while (iStatus != 0);
+        return iStatus;
+        //p.waitFor();
+    }
+
+    protected int execPS(String args) throws Exception {
+        int iStatus = 0;
+        do {
+            if (iStatus != 0) {
+                log(args + " failed. Retrying...");
+            }
+            Process p = Runtime.getRuntime().exec("powershell.exe " + args);
+            BufferedReader sr = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String line = null;
+            while ((line = sr.readLine()) != null) {
+                System.out.println(line);
+            }
+            sr.close();
+            iStatus = p.exitValue();
+        } while (iStatus != 0);
+        return iStatus;
+        //p.waitFor();
+    }
+
+    protected int fileAge(String fname) {
+        File f = new File(fname);
+        long ms = 99999999;
+        if (f.exists()) {
+            ms = (new Date().getTime()) - f.lastModified();
+        }
+        return (int) ms / 1000;
+    }
+        protected XMLHelper getManifest() throws Exception{
+        //Read the Manifest and Schemas xml
+//        if (fileAge("all-manifests.xml") > 7200) {
+//            execScope("copy -overwrite https://cosmos15.osdinfra.net/cosmos/IEBKS.Partner/shares/IEBKS.PRODDATA/raw/schema/common/all-manifests.xml all-manifests.xml");
+//        }
+        XMLHelper oMan = new XMLHelper();
+        oMan.load(getCommon("all-manifests.xml"));
+//        if (fileAge("all-schemas.xml") > 7200) {
+//            execScope("copy -overwrite https://cosmos15.osdinfra.net/cosmos/IEBKS.Partner/shares/IEBKS.PRODDATA/raw/schema/common/all-schemas.xml all-schemas.xml");
+//        }
+        XMLHelper allSchemas = new XMLHelper();
+        allSchemas.load(getCommon("all-schemas.xml"));
+        oMan.appendNode(allSchemas);
+        return oMan;
+    }
+        protected InputStream getCommon(String zFile) throws Exception{
+            URL url = new URL("https://cosmos15.osdinfra.net/cosmos/IEBKS.Partner/shares/IEBKS.PRODDATA/raw/schema/common/" + zFile);
+            URLConnection uc = url.openConnection();
+            String userpass = "senrep@microsoft.com:Game$B1Pass!!!!";
+            String basicAuth = "Basic " + new String(new Base64().encode(userpass.getBytes()));
+            uc.setRequestProperty ("Authorization", basicAuth);
+            return uc.getInputStream();
+        }
+    protected XMLHelper getManifest(String zTitleId) throws Exception{
+        return getManifest(zTitleId, null);
+    }
+    protected XMLHelper getManifest(String zTitleId, String zDate) throws Exception{
+        XMLHelper oMan = getManifest();
+        HashMap<String, String> oArgs = new HashMap<>();
+        oArgs.put("title_id", zTitleId);
+        if (zDate != null) {
+            oArgs.put("date", zDate);
+        }
+        XMLHelper oAll = oMan.transform("/xsl/scopeschema.xsl", oArgs);
+        return oAll;
+    }
+    protected XMLHelper GetXML(String args) throws Exception {
+        int iStatus = 0;
+        XMLHelper oDOM = new XMLHelper();
+        boolean loadOK = true;
+        do {
+            if (iStatus != 0 || !loadOK) {
+                log(args + " failed. Retrying...");
+            }
+            try {
+                Process p = Runtime.getRuntime().exec(SCOPE_EXE + " " + args);
+                loadOK = oDOM.load(p.getInputStream());
+                iStatus = p.exitValue();
+            } catch (Exception ex) {
+                iStatus = 1;
+            }
+        } while (iStatus != 0 || !loadOK);
+        return oDOM;
+    }
+
+}

+ 99 - 0
src/com/cloudsoft/utils/SimpleMail.java

@@ -0,0 +1,99 @@
+/*
+ * SimpleMail.java
+ *
+ * Created on March 19, 2007, 10:38 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+
+
+/** Creates a new instance of SimpleMail */
+import javax.mail.*;
+import javax.mail.internet.*;
+import javax.mail.Authenticator;
+import javax.mail.PasswordAuthentication;
+
+import java.util.Properties;
+
+
+/**
+ *
+ * @author paul
+ */
+public class SimpleMail
+{
+    
+    
+//    String  d_email = "paul.lisewski@gmail.com",
+//            d_password = "harry1996",
+//            d_host = "smtp.gmail.com",
+//            d_port  = "465",
+//            m_from = "lisewski@yahoo.com",
+//            m_to = "paul.lisewski@gmail.com",
+//            m_subject = "Testing",
+//            m_text = "Hey, this is the testing email.";
+    
+    String  d_email = "spigbi@outlook.com",
+            d_password = "Game$B1Pass!",
+            d_host = "smtp.live.com",
+            d_port  = "587",
+            m_from = d_email,
+            m_to = "a-palise@microsoft.com",
+            m_subject = "Testing",
+            m_text = "Hey, this is the testing email.";
+
+    public SimpleMail()
+    {
+        Properties props = new Properties();
+        props.put("mail.smtp.user", d_email);
+        props.put("mail.smtp.host", d_host);
+        props.put("mail.smtp.port", d_port);
+        props.put("mail.smtp.starttls.enable","true");
+        props.put("mail.smtp.auth", "true");
+//        props.put("mail.smtp.debug", "true");
+//        props.put("mail.smtp.socketFactory.port", d_port);
+//       props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+//        props.put("mail.smtp.socketFactory.fallback", "false");
+        
+//        SecurityManager security = System.getSecurityManager();
+        
+        try
+        {
+            Authenticator auth = new SMTPAuthenticator();
+            Session session = Session.getInstance(props, auth);
+//            Session session = Session.getInstance(props);
+            session.setDebug(true);
+            
+            MimeMessage msg = new MimeMessage(session);
+            msg.setText(m_text);
+            msg.setSubject(m_subject);
+            msg.setFrom(new InternetAddress(m_from));
+            msg.addRecipient(Message.RecipientType.TO, new InternetAddress(m_to));
+            Transport.send(msg);
+        }
+        catch (Exception mex)
+        {
+            mex.printStackTrace();
+        }
+    }
+        /**
+         * @param args the command line arguments
+         */
+        public static void main(String[] args) throws Exception
+        {
+            SimpleMail s = new SimpleMail();
+        }
+        private class SMTPAuthenticator extends javax.mail.Authenticator
+        {
+            public PasswordAuthentication getPasswordAuthentication()
+            {
+                String username = d_email;
+                String password = d_password;
+                return new PasswordAuthentication(username, password);
+            }
+        }
+        
+    }

+ 744 - 0
src/com/cloudsoft/utils/UIHelper.java

@@ -0,0 +1,744 @@
+/*
+ * UIHelper.java
+ *
+ * Created on 22 August 2007, 18:40
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+package com.cloudsoft.utils;
+
+/**
+ *
+ * @author paul
+ */
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.util.Enumeration;
+import java.util.HashMap;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.jsp.HttpJspPage;
+import javax.servlet.jsp.JspWriter;
+import org.json.JSONObject;
+//import javax.servlet.jsp.PageContext;
+
+public abstract class UIHelper extends ErrHelper implements HttpJspPage
+{
+
+    protected ServletConfig config;
+    protected HttpServletRequest request;
+    protected HttpServletResponse response;
+    protected ServletContext context;
+    //protected PageContext pageContext;
+    private HashMap<String, String> oSyncKeys = new HashMap<String, String>();
+    protected String zgPageTitle = "";
+    protected String zgRootDirectory = "";
+    protected String zgRootWeb = "";
+    protected String zgFullRootWeb = "";
+    protected String zgUser = "";
+    protected int zgRowsPerPage = 20;
+    protected String gPrevPage = "";
+    protected String gCurrentPage = "";
+    protected String gCurrentTab = "";
+    protected String zgGlobalName = "";
+    protected String zgSecurity = "";
+    protected XMLHelper oBranding;
+    protected HttpSession session = null;
+    protected ServletContext application = null;
+    protected JspWriter out = null;
+    //protected PrintWriter out = null;
+    protected Boolean bTopCalled = false;
+    protected long glStart;
+    protected static final javax.servlet.jsp.JspFactory _jspxFactory =
+            javax.servlet.jsp.JspFactory.getDefaultFactory();
+
+    @Override
+    public void init(ServletConfig config) throws ServletException
+    {
+        this.config = config;
+        jspInit();
+
+    }
+
+    @Override
+    public void jspInit()
+    {
+    }
+
+    @Override
+    public void destroy()
+    {
+        jspDestroy();
+    }
+
+    @Override
+    final public ServletConfig getServletConfig()
+    {
+        return config;
+    }
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
+    {
+        glStart = new java.util.Date().getTime();
+        request = (HttpServletRequest) req;
+        response = (HttpServletResponse) res;
+        //pageContext = _jspxFactory.getPageContext(this, request, response, null, true, JspWriter, true);
+        context = config.getServletContext();
+        session = request.getSession();
+        zgRootDirectory = context.getRealPath("") + "/";
+        //zgRootDirectory = zgRootDirectory.substring(0, zgRootDirectory.length() - 1);
+        zgRootWeb = request.getContextPath() + "/";
+        zgFullRootWeb = "http://" + request.getServerName() + zgRootWeb;
+        zgUser = ""; //request.getRemoteUser().toUpperCase();
+        //spStartTime = new java.util.Date().getTime();
+        gPrevPage = request.getHeader("gPrevPage");
+        gCurrentPage = request.getRequestURI();
+        gCurrentPage = gCurrentPage.substring(gCurrentPage.lastIndexOf('/')+1);
+        if (gCurrentPage.equals(""))
+            gCurrentPage = "index.jsp";
+
+        gCurrentTab = "";
+        loadSyncKeys();
+        if (gCurrentPage.equals(gPrevPage))
+        {
+            gCurrentTab = request.getHeader("gCurrentTab");
+//        try
+//        {
+        }
+        _jspService(request, response);
+//        }
+//        catch (Exception ex)
+//        {
+//            out.write("Error : " + ex.getMessage());
+//        }
+    }
+
+    @Override
+    public void jspDestroy()
+    {
+        config = null;
+    }
+
+    @Override
+    public String getServletInfo()
+    {
+        return "JSP's super class";
+    }
+
+    /**
+     * abstract method to be provided by the JSP processor in the subclass Must
+     * be defined in subclass.
+     */
+//abstract public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
+    public abstract void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException;
+
+    public void Brand_Head(JspWriter out, String zPageTitle)
+    {
+        try
+        {
+            this.out = out;
+            zgPageTitle = zPageTitle;
+            //WADS REQUIREMENT: 5.1.6
+            response.setContentType("text/html;charset=utf-8");
+            response.setHeader("Expires","Sat, 6 May 1995 12:00:00"); //Set to expire far in the past
+            response.setHeader("Cache-Control","no-cache, no-store, mustrevalidate"); //Standard HTTP 1.1
+            response.addHeader("Cache-Control","post-check=0,precheck=0"); //Set IE extended HTTP 1.1 no-cache headers
+            response.addHeader("X-Frame-Options", "SAMEORIGIN");
+            response.addHeader("X-XSS-Protection", "1; mode=block");
+            response.setHeader("Pragma","no-cache"); //Standard HTTP 1.0
+            response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
+            //WADS REQUIREMENT: 5.1.1
+            out.println("<meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>");
+//out.println("<link href='" + zgRootWeb + "Styles/new.css' rel='stylesheet' type='text/css' />");
+//            out.println("<title>" + zgPageTitle + "</title>");
+//            out.println("<script>");
+//            out.println("   zgRootWeb = '" + zgRootWeb + "';");
+//            out.println("</script>");
+//            out.println("<script language='Javascript' src='" + zgRootWeb + "js/CommonUtils.js'></script>");
+        } catch (Exception ex)
+        {
+        }
+    }
+
+    public void Brand_BodyTop(String zMenu)
+    {
+        try
+        {
+            bTopCalled = true;
+
+            XMLHelper oMenu = new XMLHelper();
+            oMenu.load("menu/" + zgSystem + "Menu.xml");
+            oBranding = oMenu.transform("menu/" + zgSystem + "Branding.xsl", new String[]
+                    {
+                        zgSystem, zMenu, zgRootWeb, zgRootWeb, zgPageTitle, getSyncKey("tab")
+                    });
+            out.println("<div id='wrapper'>");
+            XMLHelper oHead = oBranding.getNode("head");
+            out.println(oHead.getInnerXML());
+
+            // Get the side menu XML
+            if (!zMenu.equals(""))
+            {
+                XMLHelper oSide = oBranding.getNode("side");
+                out.println(oSide.getInnerXML());
+            }
+            out.println("<input type='hidden' id='csrf_token' value='" + ifNull(session.getAttribute("csrf_token"), "") + "'/>");
+            //XMLHelper oTitle = oBranding.getNode("title");
+            //out.println(oTitle.getInnerXML());
+            //out.println("<div id='content'>\r\n");
+        } catch (Exception ex)
+        {
+        }
+    }
+
+    public void Brand_BodyBottom()
+    {
+        try
+        {
+            gPrevPage = gCurrentPage;
+            //writeSyncKeysToInput();
+
+            if (bTopCalled)
+            {
+                //out.print("            </div>\r\n");
+//                out.print("        </td>\r\n");
+//                out.print("    </tr>\r\n");
+//                out.print("</table>\r\n");
+//                out.print("</td>\r\n");
+//                out.print("</tr>\r\n");
+//                out.print("</table>\r\n");
+                XMLHelper oBottom = oBranding.getNode("bottom");
+                out.print(oBottom.getInnerXML());
+            }
+            if (bTopCalled)
+            {
+                out.println("<script language = \"javascript\">");
+                //out.print("divGlobalName.innerHTML = \"" + zgGlobalName + "\";\r\n");
+
+                long lEnd = new java.util.Date().getTime();
+
+                long lDiff = lEnd - glStart;
+                String zDiff = "";
+                if (lDiff < 1000)
+                {
+                    zDiff = lDiff + " milliseconds";
+                } else
+                {
+                    zDiff = (lDiff / 1000) + " seconds";
+                }
+
+                out.println("document.getElementById(\"idCopyright\").title = \"Render Time : " + zDiff + "\";");
+
+                out.println("</script>");
+                out.println("</div>");
+            }
+
+            //write sync key information to page
+            //writeSyncKeys();
+
+
+        } catch (Exception ex)
+        {
+        }
+    }
+
+   public String generateCSRFToken(int size) throws NoSuchAlgorithmException {
+       SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+       byte[] random = new byte[size];
+       
+       sr.nextBytes(random);
+       return byteToBase64(random);
+   }
+  
+    public XMLHelper executeBizRule(String zClass, String zMethod, XMLHelper oRequest) throws Exception
+    {
+        return executeBizRule(zClass, zMethod, oRequest, true);
+    }
+
+    public XMLHelper executeBizRule(String zClass, String zMethod, XMLHelper oRequest, Boolean bDisplayErrors) throws Exception
+    {
+        Method oMethod;
+        Class<?> oClass;
+        try
+        {
+            oClass = Class.forName(zClass);
+            Class params[] = new Class[1];
+            params[0] = XMLHelper.class;
+            oMethod = oClass.getMethod(zMethod, params);
+        } catch (Exception ex)
+        {
+            handleError(ex);
+            return null;
+        }
+
+        try
+        {
+            Object o = oClass.newInstance();
+            XMLHelper oResponse;
+            if (oMethod.getReturnType().equals(XMLHelper.class))
+            {
+                Object[] oParams = new Object[]
+                {
+                    oRequest
+                };
+                oResponse = (XMLHelper) oMethod.invoke(o, oParams);
+            } else
+            {
+                String zResponseXML = (String) oMethod.invoke(o, new Object[]
+                        {
+                            oRequest.getXML()
+                        });
+                oResponse = new XMLHelper(zResponseXML);
+            }
+            return oResponse;
+        } catch (InvocationTargetException err)
+        {
+            throwError(err.getCause().getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Creates a new standard request in the format <request type="method">
+     * <system>system</system> <user>user<user> </request>
+     *
+     * @param zMethod
+     * @return
+     */
+    public XMLHelper newRequest(String zMethod)
+    {
+        XMLHelper oRequest = new XMLHelper();
+        return oRequest.createStandardRequest(zMethod, zgUser, zgSystem);
+    }
+
+    public void createPaging(int lCurrentPage, int lRows, int lRowsPerPage)
+    {
+        try
+        {
+            int i;
+            int lPageSet;
+            int lFirst;
+            int lLast;
+            int lPages = 0;
+            if (lRows > 0)
+            {
+                lPages = ((lRows - 1) / lRowsPerPage) + 1;
+            }
+            if ((lCurrentPage == 0) || (lPages == 0))
+            {
+                return;
+            }
+            lPageSet = ((lCurrentPage - 1) / 10) + 1;
+            lFirst = ((lPageSet - 1) * lRowsPerPage) + 1;
+            lLast = lPageSet * 10;
+            if (lLast > lPages)
+            {
+                lLast = lPages;
+            }
+            out.println("<table width=\"100%\">");
+            out.println("  <tr>");
+            out.print("    <td align=\"left\"><font face=\"Verdana,Arial\" size=\"1\">Currently viewing page ");
+            out.print(lCurrentPage);
+            out.print(" out of ");
+            if (lPages == 200)
+            {
+                out.print("at least 200");
+            } else
+            {
+                out.print(lPages);
+            }
+            out.print(" pages.</font></td>\r\n");
+            out.print("    <td align=\"right\">Total found : ");
+            out.print(lRows);
+            if (lPages == 200)
+            {
+                out.print("+");
+            }
+            out.println("</td>");
+            out.println("  </tr>");
+            out.println("  <tr><td colspan=\"2\">");
+            out.println("    <table><tr>");
+            if (lPageSet > 1)
+            {
+                out.println("");
+                out.print("<td class=\"nextprev\"><A HREF=\"Javascript: document.forms[0].Page.value=");
+                out.print(lFirst - 10);
+                out.println(";document.forms[0].submit()\"><font face=\"marlett\">33</font>prev 10</A> </td>");
+            }
+            for (i = lFirst; i < lLast + 1; i++)
+            {
+                if (i > 0 && i <= lPages)
+                {
+                    if (i == lCurrentPage)
+                    {
+                        out.print("\t    <td class=\"pageno\">[");
+                        out.print(i);
+                        out.println("]</td>");
+                    } else
+                    {
+                        out.println("");
+                        out.print("\t<td class=\"pageno\"><a href=\"Javascript: document.forms[0].Page.value=");
+                        out.print(i);
+                        out.print(";document.forms[0].submit()\">");
+                        out.print(i);
+                        out.println("</a></td>");
+                    }
+                }
+            }
+            if (lLast < lPages)
+            {
+                out.println("");
+                out.print("    <td class=\"nextprev\"><A HREF=\"Javascript: document.forms[0].Page.value=");
+                out.print(lLast + 1);
+                out.println(";document.forms[0].submit()\">next 10<font face=\"marlett\">44</font></A></td>");
+            }
+            out.println("    </tr></table>");
+            out.println("  </td></tr>");
+            out.println("</table>");
+        } catch (Exception ex)
+        {
+        }
+    }
+//   XML Stuff
+
+    public void transformSQL(String zSQL, String xslFile, int iStartRow, int iMaxRows, boolean bShowTotal) throws Exception
+    {
+        xslFile = context.getRealPath(xslFile);
+        DBHelper o = new DBHelper();
+        XMLHelper oDOM = o.getDOM(zSQL, iStartRow, iMaxRows, bShowTotal, "rows", "row", false);
+        oDOM.transform(xslFile, out);
+    }
+
+    public XMLHelper getDOM(String zSQL, int iStartRow, int iMaxRows, boolean bShowTotal) throws Exception
+    {
+        DBHelper o = new DBHelper();
+        return o.getDOM(zSQL, iStartRow, iMaxRows, bShowTotal, "rows", "row", false);
+    }
+
+    public XMLHelper getDOM(String zSQL, int iStartRow, int iMaxRows, boolean bShowTotal, String zRowset, String zRow) throws Exception
+    {
+        DBHelper o = new DBHelper();
+        return o.getDOM(zSQL, iStartRow, iMaxRows, bShowTotal, zRowset, zRow, false);
+    }
+
+    public void transformXML(String xmlFile, String xslFile)
+    {
+        transformXML(xmlFile, xslFile, new String[]
+                {
+                });
+    }
+
+    public void transformXML(XMLHelper oDOM, String xslFile)
+    {
+        oDOM.transform(context.getRealPath(xslFile), out);
+    }
+
+    public void transformXML(XMLHelper oDOM, String xslFile, String[] aParams)
+    {
+        oDOM.transform(context.getRealPath(xslFile), aParams, out);
+    }
+
+    public void transformXML(String xmlFile, String xslFile, String[] aParams)
+    {
+        XMLHelper oDOM = new XMLHelper();
+        oDOM.load(context.getRealPath(xmlFile));
+        oDOM.transform(context.getRealPath(xslFile), aParams, out);
+    }
+
+    public XMLHelper transformDOM(String xmlFile, String xslFile, String[] aParams)
+    {
+        XMLHelper oDOM = new XMLHelper();
+        oDOM.load(context.getRealPath(xmlFile));
+        return oDOM.transform(context.getRealPath(xslFile), aParams);
+    }
+
+    public void transformPDF(String xmlFile, String xslFile)
+    {
+        try
+        {
+            XMLHelper oDOM = new XMLHelper();
+            oDOM.load(context.getRealPath(xmlFile));
+            transformPDF(oDOM, xslFile, "pdf.pdf");
+        } catch (Exception oEx)
+        {
+            try
+            {
+                out.println(oEx.getMessage() + "<br/>");
+            } catch (Exception ex1)
+            {
+            }
+        }
+    }
+
+    public void transformPDF(XMLHelper oDOM, String xslFile, String reportName)
+    {
+        transformPDF(oDOM, xslFile, null, reportName);
+    }
+    public void transformPDF(XMLHelper oDOM, String xslFile, HashMap<String, String> aParams, String reportName)
+    {
+        try
+        {
+            response.setContentType("application/pdf");
+            response.setHeader("Content-Disposition", "attachment;filename=" + reportName.replace(" ", "_"));
+            oDOM.transformPDFJar(xslFile, aParams, response.getOutputStream());
+            //byte[] content = oDOM.transformPDF(xslFile);
+            //response.setContentLength(content.length);
+            //for (int i=0; i < content.length; i++)
+            //                out.write(content[i]);
+            //out.flush();
+            //out.print(content);
+            //out.flush();
+        } catch (Exception oEx)
+        {
+            try
+            {
+                out.println(oEx.getMessage() + "<br/>");
+            } catch (Exception ex1)
+            {
+            }
+        }
+    }
+
+    public String getRequestXML(HttpServletRequest req)
+    {
+        Enumeration e = req.getParameterNames();
+        String zXML = "<parameters>";
+        while (e.hasMoreElements())
+        {
+            String key = (String) e.nextElement();
+            zXML += "<parameter name=\"" + key + "\">";
+            String[] values = req.getParameterValues(key);
+            for (int i = 0; i < values.length; i++)
+            {
+                zXML += values[i] + " ";
+            }
+            zXML += "</parameter>";
+        }
+        zXML += "</parameters>";
+        return (zXML);
+    }
+    /// <summary>
+    /// write SyncKeys to Hidden Fields Should be overriden to include another systems sync keys
+    /// </summary>
+
+    public void loadSyncKeys()
+    {
+        // Add your SyncKeys Here
+        SyncKey("tab");
+
+    }
+
+    /// <summary>
+    /// Sets a Sync key.
+    /// </summary>
+    /// <param name="zName">Name of the Sync Key</param>
+    public void SyncKey(String zName)
+    {
+        zName = "g_" + zName;
+        String zValue = request.getParameter(zName);
+        if (zValue == null)
+        {
+            zValue = "";
+        }
+
+        oSyncKeys.put(zName, zValue);
+    }
+
+    public String getSyncKey(String zName)
+    {
+        zName = "g_" + zName;
+        return oSyncKeys.get(zName);
+    }
+
+    public void setSyncKey(String zName, String zValue)
+    {
+        zName = "g_" + zName;
+        oSyncKeys.put(zName, zValue);
+    }
+
+    public void writeSyncKeys() throws Exception
+    {
+        for (String zSyncKey : oSyncKeys.keySet())
+        {
+            out.println("\t setSyncKey(\"" + zSyncKey + "\", \"" + oSyncKeys.get(zSyncKey) + "\");");
+        }
+    }
+
+    public void writeSyncKeysToInput() throws Exception
+    {
+        for (String zSyncKey : oSyncKeys.keySet())
+        {
+            out.println("<input type=\"hidden\" name=\"" + zSyncKey + "\" value=\"" + oSyncKeys.get(zSyncKey) + "\" />");
+        }
+    }
+    /// <summary>
+    /// Returns a default of the checked value is null otherwise it returns a the value to check
+    /// </summary>
+    /// <param name="oCheck">Value to check.</param>
+    /// <param name="zDefault">The default.</param>
+    /// <returns>Either the Checked value or the default depending on whether the checked value is null</returns>
+
+    public String ifNull(Object oCheck, String zDefault)
+    {
+        if (oCheck == null)
+        {
+            return zDefault;
+        } else
+        {
+            return oCheck.toString();
+        }
+    }
+    public Integer ifNull(Object oCheck, Integer iDefault)
+    {
+        if (oCheck == null)
+        {
+            return iDefault;
+        } else
+        {
+            return (Integer)oCheck;
+        }
+    }
+
+    public void createFile(String zPath, String zText) throws Exception
+    {
+        FileWriter fw;
+        try
+        {
+            fw = new FileWriter(zPath);
+        } catch (IOException ex)
+        {
+            String dir = zPath.substring(0, zPath.lastIndexOf('\\'));
+            new File(dir).mkdirs();
+            fw = new FileWriter(zPath);
+        }
+        fw.write(zText);
+        fw.close();
+
+    }
+
+    public XMLHelper getLookups(XMLHelper oRequest, String zSQL) throws Exception
+    {
+        DBHelper oDB = new DBHelper(oRequest);
+        return oDB.getDOM(zSQL, 0, 999, false, "", "lookup", false);
+    }
+
+    public XMLHelper serialiseJSON(String json)
+    {
+        XMLHelper oRequest = newRequest(ifNull(request.getParameter("type"), "invalid"));
+        JSONObject o = new JSONObject(json);
+        String xml = org.json.XML.toString(o);
+        XMLHelper oJson = new XMLHelper("<request>" + xml + "</request>");
+        oRequest.appendNode(oJson.getChildNodes());
+        return oRequest;
+    }
+    public XMLHelper serialiseJSON()
+    {
+        XMLHelper oRequest = newRequest(ifNull(request.getParameter("type"), "invalid"));
+        Enumeration e = request.getParameterNames();
+        while (e.hasMoreElements())
+        {
+            String zName = (String) e.nextElement();
+            if (zName != null)
+            {
+                String[] pValues = request.getParameterValues(zName);
+                XMLHelper oRow = oRequest;
+                if (zName.contains("["))
+                {
+                    String[] arr = zName.split("\\[");
+                    String zRowName = "row";
+                    String zRowID = arr[0];
+                    zName = arr[1].substring(0, arr[1].length() - 1);
+                    if (arr.length >= 3)
+                    {
+                        zRowName = arr[0];
+                        zRowID = arr[1].substring(0, arr[1].length() - 1);
+                        zName = arr[2].substring(0, arr[2].length() - 1);
+                    }
+                    if (oRequest.nodeCount(zRowName + "[@id='" + zRowID + "']") == 0)
+                    {
+                        oRow = oRequest.appendNode(zRowName);
+                        oRow.appendAttribute("id", zRowID);
+                    } else
+                    {
+                        oRow = oRequest.getNode(zRowName + "[@id='" + zRowID + "']");
+                    }
+                    if (arr.length > 3)
+                    {
+                        zRowName = zName;
+                        zRowID = arr[3].substring(0, arr[3].length() - 1);
+                        zName = arr[4].substring(0, arr[4].length() - 1);
+                        if (oRow.nodeCount(zRowName + "[@id='" + zRowID + "']") == 0)
+                        {
+                            oRow = oRow.appendNode(zRowName);
+                            oRow.appendAttribute("id", zRowID);
+                        } else
+                        {
+                            oRow = oRow.getNode(zRowName + "[@id='" + zRowID + "']");
+                        }
+                    }
+                }
+                for (int j = 0; j < pValues.length; j++)
+                {
+                    String value = (zName.endsWith("_text") ? HTMLDecode(pValues[j]).replaceAll("\r\n", "") : HTMLEncode(pValues[j]));
+                    oRow.appendNode((zName.equals("")) ? Integer.toString(j) : zName.replaceAll(" ", "_"), value);
+                }
+            }
+        }
+        return oRequest;
+
+    }
+
+    public XMLHelper serialisePost()
+    {
+        XMLHelper oRequest = new XMLHelper("request");
+        oRequest.appendNode("system", zgSystem);
+        if (zgSecurity.equals("OFF"))
+        {
+            oRequest.appendAttribute("sec", "off");
+        }
+        Enumeration e = request.getParameterNames();
+        while (e.hasMoreElements())
+        {
+            String name = (String) e.nextElement();
+            if (name != null)
+            {
+                String value = request.getParameter(name);
+                if (name.charAt(0) == '_')
+                {
+                    if (name.length() > 1)
+                    {
+                        oRequest.appendAttribute(name.substring(1), value);
+                    }
+                } else
+                {
+                    //Sync Keys
+                    if (name.startsWith("g_"))
+                    {
+                        String zField = name.substring(2);
+                        if (ifNull(request.getParameter(zField), "").equals(""))
+                        {
+                            oRequest.setNode(zField, value);
+                        }
+                    } else
+                    {
+                        oRequest.appendNode(name, value);
+                    }
+                }
+            }
+        }
+        return oRequest;
+    }
+}

+ 240 - 0
src/com/cloudsoft/utils/WebProxy.java

@@ -0,0 +1,240 @@
+/*
+ * WebProxy.java
+ *
+ * Created on 12 July 2006, 13:25
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package com.cloudsoft.utils;
+
+import java.net.*;
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+/**
+ *
+ * @author pyl38997
+ */
+public class WebProxy
+{
+    private String sOutput;
+    private int iPos;
+    /** Creates a new instance of WebProxy */
+    public WebProxy()
+    {
+    }
+
+    public String getText(String url)
+    {
+        try 
+        {
+            sOutput = "";
+            StringWriter sw = new StringWriter();
+            URL u = new URL(url);
+            //System.setProperty("proxySet", "true" );
+            //System.setProperty("http.proxyHost", "brenc04.corpnet2.com" );
+            //System.setProperty("http.proxyPort", "800");
+            HttpURLConnection huc = (HttpURLConnection) u.openConnection();
+            huc.setRequestMethod("GET");
+            huc.connect();
+            InputStream in = huc.getInputStream();
+            int c;
+            while ((c = in.read()) != -1)
+                sw.write(c);
+            in.close();
+            huc.disconnect();
+            sOutput = sw.toString();
+            iPos = 0;
+        }
+        catch (IOException e) 
+        {
+            System.out.println("Error : " + e.getMessage());
+        }      
+        return (sOutput);
+    }
+
+    public int moveTo(String s)
+    {
+        iPos = sOutput.indexOf(s, iPos);
+        return (iPos);
+    }
+    
+    public String getBetween(String sFrom, String sTo)
+    {
+        int iFrom = sOutput.indexOf(sFrom, iPos);
+        if (iFrom != -1)
+            iFrom += sFrom.length();
+        int iTo = sOutput.indexOf(sTo, iFrom);
+        if (iTo != -1)
+        {
+            iPos = iTo;
+            return (sOutput.substring(iFrom, iPos));
+        }
+        else
+            return ("");
+    }
+    public static void main(String[] args)
+    {
+        // Test simple Load
+        //testMove();
+        try
+        {
+        testLoad1();
+        }
+        catch (Exception ex)
+        {
+            
+        }
+    }   
+
+    private static void testMove()
+    {
+        WebProxy oWeb = new WebProxy();
+        String s = oWeb.getText("http://finance.yahoo.com/q/hp?s=GSK.L");
+        //System.out.println(s);
+        oWeb.moveTo("yfnc_tablehead1");
+        while (oWeb.moveTo("yfnc_tabledata1") != -1)
+        {
+            System.out.println(oWeb.getBetween(">", "<"));
+        }
+    }
+    private static void testLoad() throws Exception
+    {
+        DBHelper oDB = new DBHelper("stock");
+        String zSQL = "select s.*," +
+                " (select max(price_date) + 1 from sd_daily_prices dp where dp.stock_id = s.stock_id) as max_date" +
+                " from sd_stocks s";
+        XMLHelper oDOM = oDB.getDOM(zSQL, 0,0,false,"stocks","stock", false);
+        XMLHelper[] aStock = oDOM.getNodes("//stock");
+        WebProxy oWeb = new WebProxy();
+        DateFormat df = new SimpleDateFormat("dd-MMM-yy");
+        Date dt = new Date();
+        GregorianCalendar dTo;
+        GregorianCalendar dFrom;
+        for (int i=0; i < aStock.length; i++)
+        {
+            XMLHelper oStock = aStock[i];
+            dTo = new GregorianCalendar();
+            
+            if (oStock.getDate("max_date") == null)
+                dFrom = new GregorianCalendar(2000,0,1);
+            else
+            {
+                dFrom =  new GregorianCalendar();
+                dFrom.setTime(oStock.getDate("max_date"));
+            }
+            
+            while (dFrom.before(dTo))
+            {
+                //String zCVS = oWeb.getText("http://ichart.finance.yahoo.com/table.csv?s=" + oStock.getString("symbol") + "&d=" + dTo.get(Calendar.MONTH) + "&e=" + dTo.get(Calendar.DATE) + "&f=" + dTo.get(Calendar.YEAR) + "&g=d&a=" + dFrom.get(Calendar.MONTH) + "&b=" + dFrom.get(Calendar.DATE) + "&c=" + dFrom.get(Calendar.YEAR));
+                String zCVS = oWeb.getText("http://ichart.finance.yahoo.com/table.csv?s=" + oStock.getString("symbol") + "&d=" + dTo.get(Calendar.MONTH) + "&e=" + dTo.get(Calendar.DATE) + "&f=" + dTo.get(Calendar.YEAR) + "&g=d&a=" + dFrom.get(Calendar.MONTH) + "&b=" + dFrom.get(Calendar.DATE) + "&c=" + dFrom.get(Calendar.YEAR));
+                String[] aLines = zCVS.split("\n");
+                String[] aData = {};
+                for (int j=1; j < aLines.length; j++)
+                {
+                    aData = aLines[j].split(",");
+                    //XMLHelper oDay = oDays.appendNode("day");
+                    zSQL = "insert into sd_daily_prices values (nextval('seq_daily_prices'), ";
+                    zSQL += "'" + oStock.getString("stock_id") + "', ";
+                    zSQL += "'" + aData[0] + "', ";
+                    zSQL += aData[1] + ", ";
+                    zSQL += aData[4] + ", ";
+                    zSQL += aData[2] + ", ";
+                    zSQL += aData[3] + ", ";
+                    zSQL += aData[5] + ", ";
+                    zSQL += aData[6] + ")";
+                    oDB.execute(zSQL);
+                }
+                try
+                {
+                    Date dlast = (aData.length == 0) ? dt : df.parse(aData[0]);
+                    if (dt.equals(dlast))
+                        dTo = dFrom;
+                    else
+                    {
+                        dTo = (GregorianCalendar) df.getCalendar();
+                        dTo.add(Calendar.DATE, -1);
+                    }
+                    dt = dlast;
+                    //System.out.println(dt.toString());
+                }
+                catch (Exception ex)
+                {    
+                    System.out.println(ex.toString());
+                }
+            }
+        }
+    }
+
+    private static void testLoad1() throws Exception
+    {
+        DBHelper oDB = new DBHelper("stock");
+        String zSQL = "select s.*," +
+                " (select max(price_date) + 1 from sd_prices dp where dp.symbol = s.symbol) as max_date" +
+                " from sd_stock s";
+        XMLHelper oDOM = oDB.getDOM(zSQL, 0,0,false,"stocks","stock", false);
+        XMLHelper[] aStock = oDOM.getNodes("//stock");
+        WebProxy oWeb = new WebProxy();
+        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Date dt = new Date();
+        GregorianCalendar dTo;
+        GregorianCalendar dFrom;
+        for (int i=0; i < aStock.length; i++)
+        {
+            XMLHelper oStock = aStock[i];
+            dTo = new GregorianCalendar();
+            
+            if (oStock.getDate("max_date") == null)
+                dFrom = new GregorianCalendar(2000,0,1);
+            else
+            {
+                dFrom =  new GregorianCalendar();
+                dFrom.setTime(oStock.getDate("max_date"));
+            }
+            
+            while (dFrom.before(dTo))
+            {
+                String zCVS = oWeb.getText("http://ichart.finance.yahoo.com/table.csv?s=" + oStock.getString("symbol") + "&d=" + dTo.get(Calendar.MONTH) + "&e=" + dTo.get(Calendar.DATE) + "&f=" + dTo.get(Calendar.YEAR) + "&g=d&a=" + dFrom.get(Calendar.MONTH) + "&b=" + dFrom.get(Calendar.DATE) + "&c=" + dFrom.get(Calendar.YEAR));
+                String[] aLines = zCVS.split("\n");
+                String[] aData = {};
+                for (int j=1; j < aLines.length; j++)
+                {
+                    aData = aLines[j].split(",");
+                    //XMLHelper oDay = oDays.appendNode("day");
+                    zSQL = "insert into sd_prices values ( ";
+                    zSQL += "'" + oStock.getString("symbol") + "', ";
+                    zSQL += "'" + aData[0] + "', ";
+                    zSQL += aData[1] + ", ";
+                    zSQL += aData[4] + ", ";
+                    zSQL += aData[2] + ", ";
+                    zSQL += aData[3] + ", ";
+                    zSQL += aData[5] + ", ";
+                    zSQL += aData[6] + ")";
+                    oDB.execute(zSQL);
+                }
+                oDB.commit();
+                try
+                {
+                    Date dlast = (aData.length == 0) ? dt : df.parse(aData[0]);
+                    if (dt.equals(dlast))
+                        dTo = dFrom;
+                    else
+                    {
+                        dTo = (GregorianCalendar) df.getCalendar();
+                        dTo.add(Calendar.DATE, -1);
+                    }
+                    dt = dlast;
+                    //System.out.println(dt.toString());
+                }
+                catch (Exception ex)
+                {    
+                    System.out.println(ex.toString());
+                }
+            }
+        }
+    }
+    
+}

+ 1471 - 0
src/com/cloudsoft/utils/XMLHelper.java

@@ -0,0 +1,1471 @@
+/*
+ * XMLHelper.java
+ *
+ * Created on 24 June 2003, 15:00
+ */
+package com.cloudsoft.utils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URL;
+import java.sql.Connection;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FopFactoryBuilder;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.xmlgraphics.io.ResourceResolver;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * XML Helper
+ *
+ * @author PYL38997
+ */
+public class XMLHelper extends ErrHelper {
+
+    // Declare module level variables
+    /**
+     * The XALAN Node that this XMLHelper wraps
+     */
+    public Node omNode;
+    private Document _doc = null;
+    static XPath _xpath = null;
+    private Pattern _DatePattern = null;
+    private Pattern _SimplePattern = null;
+    private Pattern _MediumPattern = null;
+    private Pattern _CSVPattern = null;
+    private Pattern _TSVPattern = null;
+    private static final String _QUOTE = "\"";
+    protected Connection _con = null;
+    private String _DateFormat = "dd-MMM-yyyy";
+    private String _AltDateFormat = "yyyy-MM-dd";
+    private ResourceResolver _pdfResolver = null;
+    /**
+     * Creates a new instance of XMLHelper
+     */
+    public XMLHelper() {
+    }
+
+    /**
+     * Creates a new instance of XMLHelper with the base node set
+     *
+     * @param zRoot the root node to create
+     */
+    public XMLHelper(String zRoot) {
+            if (zRoot.charAt(0) == '<' || !zRoot.matches("\\w*")) {
+            load(zRoot);
+        } else {
+            createRoot(zRoot);
+        }
+    }
+
+    /**
+     * Creates a new instance of XMLHelper with the base node set
+     *
+     * @param url The url to load
+     */
+    public XMLHelper(URL url) {
+        Document oDOM;
+        DocumentBuilderFactory oFactory = DocumentBuilderFactory.newInstance();
+        try {
+            DocumentBuilder oBuilder = oFactory.newDocumentBuilder();
+            InputStream stream = url.openStream();
+            oDOM = oBuilder.parse(stream);
+            oDOM.normalize();
+
+            omNode = oDOM.getFirstChild();
+            _doc = oDOM;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    /**
+     * Creates a new instance of XMLHelper with the base node set
+     *
+     * @param oNode The base node to set
+     */
+    public XMLHelper(Node oNode) {
+        omNode = oNode;
+    }
+
+    /**
+     * Creates a new instance of XMLHelper with the base node set to the first
+     * child of the Document
+     *
+     * @param oDoc Document to base this XMLHelper on
+     */
+    public XMLHelper(Document oDoc) {
+        omNode = oDoc.getFirstChild();
+        _doc = oDoc;
+    }
+
+    private Document _Document() {
+        if (_doc == null) {
+            _doc = omNode.getOwnerDocument();
+        }
+        return _doc;
+    }
+
+    private XPath Xpath() throws XPathFactoryConfigurationException {
+        if (_xpath == null) {
+            XPathFactory XPathfactory = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
+            _xpath = XPathfactory.newXPath();
+        }
+        return _xpath;
+
+    }
+
+    private Pattern DatePattern() {
+        if (_DatePattern == null) {
+            if (_DateFormat.equals("dd-MMM-yyyy")) {
+                _DatePattern = Pattern.compile("^(([0-9])|([0-2][0-9])|([3][0-1]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\\d{4}.*", Pattern.CASE_INSENSITIVE);
+            } else {
+                _DatePattern = Pattern.compile("^(19|20)\\d\\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01]).*");
+            }
+        }
+        return _DatePattern;
+    }
+
+    private Pattern SimplePattern() {
+        if (_SimplePattern == null) {
+            _SimplePattern = Pattern.compile("[a-z0-9_]*");
+        }
+        return _SimplePattern;
+    }
+
+    private Pattern MediumPattern() {
+        if (_MediumPattern == null) {
+            _MediumPattern = Pattern.compile("^[^\\/][.a-z0-9_\\/]*");
+        }
+        return _MediumPattern;
+    }
+
+    private Pattern CSVPattern() {
+        if (_CSVPattern == null) {
+            _CSVPattern = Pattern.compile("(?:^|,)\"?((?<=\")[^\"]*|[^,\"]*)\"?(?=,|$)");
+        }
+        return _CSVPattern;
+    }
+
+    private Pattern TSVPattern() {
+        if (_TSVPattern == null) {
+            _TSVPattern = Pattern.compile("(?:^|\t)\"?((?<=\")[^\"]*|[^\t\"]*)\"?(?=\t|$)");
+        }
+        return _TSVPattern;
+    }
+
+    /**
+     * Creates the root Node
+     *
+     * @param zRootName The name of the root node
+     */
+    public final void createRoot(String zRootName) {
+        load("<" + zRootName + "/>");
+    }
+
+    /**
+     * Creates a Standard Request DOM
+     *
+     * @param zType The type of request
+     * @param zUserID The user id
+     * @param zSystem The system id
+     * @return XMLHelper request Object
+     */
+    public XMLHelper createStandardRequest(String zType, String zUserID, String zSystem) {
+        this.createRoot("request");
+        this.appendAttribute("type", zType);
+        this.appendNode("mud_id", zUserID);
+        this.appendNode("system", zSystem);
+        return this;
+    }
+
+    public boolean exists(String zXPath) {
+        return (getNode(zXPath) != null && getNode(zXPath).omNode != null);
+    }
+
+    /**
+     * Appends a node to the dom
+     *
+     * @param vNodeName The name of the new node
+     * @return Returns an XMLHelper of the new Node
+     */
+    public XMLHelper appendNode(String vNodeName) {
+        Document oDoc = _Document();
+        Node oNewNode = oDoc.createElement(vNodeName);
+        omNode.appendChild(oNewNode);
+        XMLHelper oHelper = new XMLHelper(oNewNode);
+        return oHelper;
+    }
+
+    /**
+     * Appends a node to the dom and sets it's value
+     *
+     * @param vNodeName The name of the new node
+     * @param zValue The value to set the new node
+     * @param bCheckExists O
+     * @return Returns the XMLHelper for the new node
+     */
+    public XMLHelper appendNode(String vNodeName, String zValue, boolean bCheckExists) {
+        if (exists(vNodeName)) {
+            return getNode(vNodeName);
+        } else {
+            return appendNode(vNodeName, zValue);
+        }
+    }
+
+    public XMLHelper appendNode(String vNodeName, Integer iValue) {
+        return appendNode(vNodeName, iValue.toString());
+    }
+    /**
+     * Appends a node to the dom and sets it's value
+     *
+     * @param vNodeName The name of the new node
+     * @param zValue The value to set the new node
+     * @return Returns the XMLHelper for the new node
+     */
+    public XMLHelper appendNode(String vNodeName, String zValue) {
+        Document oDoc = _Document();
+        Node oNewNode = oDoc.createElement(vNodeName);
+        oNewNode.appendChild(oDoc.createTextNode(zValue == null ? "" : zValue));
+        omNode.appendChild(oNewNode);
+        XMLHelper oHelper = new XMLHelper(oNewNode);
+        return oHelper;
+    }
+
+    /**
+     * Appends an XMLHelper dom
+     *
+     * @param oDOM The DOM to append to this DOM
+     * @return Returns the XMLHelper for the new node
+     */
+    public XMLHelper appendNode(XMLHelper oDOM) {
+        Node oNew = _Document().importNode(oDOM.omNode, true);
+        omNode.appendChild(oNew);
+        return new XMLHelper(oNew);
+    }
+    /**
+     * Appends an XMLHelper dom as a named node
+     *
+     * @param vNodeName The name of the new node
+     * @param oDOM The DOM to append to this DOM
+     * @return Returns the XMLHelper for the new node
+     */
+    public XMLHelper appendNode(String vNodeName, XMLHelper oDOM) {
+        XMLHelper oNode = appendNode(vNodeName);
+        oNode.appendNode(oDOM.getChildNodes());
+        return oNode;
+    }
+    /**
+     * Appends an array of XMLHelpers
+     *
+     * @param oNodes The Nodelist to append to the existing DOM
+     */
+    public void appendNode(XMLHelper[] oNodes) {
+        for (XMLHelper oNode : oNodes) {
+            appendNode(oNode);
+        }
+    }
+
+    /// <summary>
+    /// Sets an attribute value
+    /// </summary>
+    /// <param name="zNodeName">The name of the attribute to set</param>
+    /// <param name="zValue">The value to set the attribute</param>
+    public void setAttribute(String zAttributeName, String zValue) {
+        appendAttribute(zAttributeName, zValue);
+    }
+
+    /**
+     * Appends an attribute to the dom and sets it's value
+     *
+     * @param zNodeName The name of the new node
+     * @param zValue The value to set the new node
+     */
+    public void appendAttribute(String zNodeName, String zValue) {
+//        Attr oAttr = omNode.getOwnerDocument().createAttribute(zNodeName);
+//        oAttr.setNodeValue(zValue);
+//        omNode.appendChild(oAttr);
+        Element oNode = (Element) omNode;
+        oNode.setAttribute(zNodeName, zValue);
+    }
+
+    /**
+     * Appends a node/attribute based on an XPath (like alias names in SQL)
+     *
+     * @param zXPath The name of the new node/attribute in XPath syntax
+     * @param zValue The value to set the new node
+     */
+    public void appendXPathNode(String zXPath, String zValue) {
+        try {
+            int i;
+            Node oOrig = omNode;
+            // Split the Name by "/"
+            String[] arrNodes = zXPath.split("/");
+            for (i = 0; i < arrNodes.length - 1; i++) {
+                Node oNode = getChildByTagName(arrNodes[i]);
+                //Node oNode = XPathAPI.selectSingleNode(omNode, arrNodes[i]);
+                if (oNode == null) {
+                    omNode = appendNode(arrNodes[i]).omNode;
+                } else {
+                    omNode = oNode;
+                }
+            }
+            if (arrNodes[i].charAt(0) == '@') {
+                appendAttribute(arrNodes[i].substring(1), zValue);
+            } else {
+                appendNode(arrNodes[i], zValue);
+            }
+            omNode = oOrig;
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    /**
+     * Gets the XML of the current node as a string
+     *
+     * @return Returns the XML of the current node as a string
+     */
+    public String getXML() {
+        return serializeNode(omNode);
+    }
+
+    public String getInnerXML() {
+        String zOut = "";
+        NodeList oChildren = omNode.getChildNodes();
+        for (int i = 0; i < oChildren.getLength(); i++) {
+            zOut += serializeNode(oChildren.item(i));
+        }
+        return zOut;
+    }
+
+    /**
+     * Gets the XML of the root node as a string
+     *
+     * @return Returns the XML of the root node as a string
+     */
+    public String getRootXML() {
+        return serializeNode((Node) _Document());
+    }
+
+    public void serializeNode(Writer oWriter) {
+        try {
+            serializeNode(omNode, oWriter);
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    private void serializeNode(Node oNode, Writer oWriter) {
+        serializeNode(oNode, oWriter, false);
+    }
+
+    private void serializeNode(Node oNode, Writer oWriter, boolean bNice) {
+        try {
+            TransformerFactory factory = TransformerFactory.newInstance();
+            if (bNice) {
+                factory.setAttribute("indent-number", 4);
+            }
+            Transformer transformer = factory.newTransformer();
+            if (bNice) {
+                transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            } else {
+                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            }
+            transformer.transform(new DOMSource(oNode), new StreamResult(oWriter));
+
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    public void serialize(OutputStream oOutputStream, boolean bNice) {
+        serializeNode(omNode, oOutputStream, bNice);
+    }
+
+    private void serializeNode(Node oNode, OutputStream oWriter, boolean bNice) {
+        try {
+            TransformerFactory factory = TransformerFactory.newInstance();
+            if (bNice) {
+                factory.setAttribute("indent-number", 4);
+            }
+            Transformer transformer = factory.newTransformer();
+            if (bNice) {
+                transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            } else {
+                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            }
+            transformer.transform(new DOMSource(oNode), new StreamResult(oWriter));
+
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    private String serializeNode(Node oNode) {
+        try {
+            StringWriter stringOut = new StringWriter();
+            serializeNode(oNode, stringOut);
+            return (stringOut.toString());
+        } catch (Exception ex) {
+            logError(ex);
+            return ("");
+        }
+    }
+
+    public void saveAs(String zPath) throws Exception {
+        saveAs(zPath, false);
+    }
+
+    public void saveAs(String zPath, boolean bNice) throws Exception {
+        if (zPath.endsWith(".gz")) {
+            GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(zPath));
+            serializeNode(omNode, out, bNice);
+            out.flush();
+            out.close();
+        } else {
+            FileWriter fw = new FileWriter(zPath);
+            serializeNode(omNode, fw, bNice);
+            fw.close();
+        }
+    }
+
+    /**
+     * Removes a node
+     */
+    public void removeNode() {
+        try {
+            if (omNode.getNodeType() == Node.ATTRIBUTE_NODE) {
+                ((Attr) omNode).getOwnerElement().removeAttribute(omNode.getNodeName());
+            } else {
+                omNode.getParentNode().removeChild(omNode);
+            }
+        } catch (Exception ex) {
+            // Do nothing if we can't remove the node
+        }
+
+    }
+
+    /**
+     * Removes a node
+     *
+     * @param zNodeName The name of node to remove
+     */
+    public void removeNode(String zNodeName) {
+        getNode(zNodeName).removeNode();
+    }
+
+    /**
+     * Removes all child Nodes from the current node
+     */
+    public void removeChildren() {
+        try {
+            NodeList oChildren = omNode.getChildNodes();
+            while (oChildren.getLength() > 0) {
+                omNode.removeChild(oChildren.item(0));
+            }
+        } catch (Exception ex) {
+            // Do nothing if we can't remove the node
+        }
+
+    }
+
+    public XMLHelper getFirstChild() {
+        return new XMLHelper(omNode.getFirstChild());
+    }
+
+    public XMLHelper[] getChildNodes() {
+        NodeList oNodes = omNode.getChildNodes();
+        XMLHelper[] arrNodes = new XMLHelper[oNodes.getLength()];
+        for (int i = 0; i < oNodes.getLength(); i++) {
+            arrNodes[i] = new XMLHelper(oNodes.item(i));
+        }
+        return arrNodes;
+    }
+
+    public XMLHelper getOrAddNode(String zXPath, String zValue) {
+        Node oNode;
+        int iPos = zXPath.lastIndexOf('/');
+        if (iPos > 0) {
+            String zNode = zXPath.substring(0, iPos);
+            String zID = zXPath.substring(iPos + 1);
+            try {
+                oNode = (Node) Xpath().evaluate(zNode + "[" + zID + "='" + zValue + "']", omNode, XPathConstants.NODE);
+            } catch (Exception ex) {
+                oNode = null;
+            }
+            if (oNode != null) {
+                return new XMLHelper(oNode);
+            }
+
+            XMLHelper oNew = appendNode(zNode);
+            if (zID.startsWith("@")) {
+                oNew.appendAttribute(zID.substring(1), zValue);
+            } else {
+                oNew.setNode(zID, zValue);
+            }
+            return oNew;
+        } else {
+            if (zXPath.startsWith("@")) {
+                appendAttribute(zXPath.substring(1), zValue);
+            } else {
+                setNode(zXPath, zValue);
+            }
+            return new XMLHelper(omNode);
+        }
+    }
+
+    /**
+     * Get the parent XMLHelper
+     *
+     * @return Returns the Parent node as an XMLHelper object
+     */
+    public XMLHelper getParent() {
+        XMLHelper oHelper = new XMLHelper(omNode.getParentNode());
+        return oHelper;
+    }
+
+    /**
+     * Loads a string into the DOM or a file
+     *
+     * @return Boolean indicating success or failure
+     * @param zXML Either the XML as a string or a file location
+     */
+    public final boolean load(String zXML) {
+        try {
+            InputStream oIS;
+            DocumentBuilderFactory oFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder oBuilder = oFactory.newDocumentBuilder();
+            //DOMParser oParser = new DOMParser();
+            if (zXML.charAt(0) == '<') {
+                oIS = new ByteArrayInputStream(zXML.getBytes("UTF-8"));
+                //oIS = new ByteArrayInputStream(zXML.getBytes());
+            } else {
+                oIS = getClass().getResourceAsStream(zXML);
+                if (oIS == null) {
+                    oIS = new FileInputStream(zXML);
+                }
+                if (zXML.endsWith(".gz")) {
+                    oIS = new GZIPInputStream(oIS);
+                }
+            }
+            //Reader reader = new InputStreamReader(oIS, "UTF-8");
+            //InputSource oSource = new InputSource(reader);
+            //oSource.setEncoding("UTF-8");
+            //InputSource oSource = new InputSource(oIS);
+            //Document oDOM = oBuilder.parse(oSource);
+            Document oDOM = oBuilder.parse(oIS);
+            //oDOM.normalize();
+
+            omNode = oDOM.getFirstChild();
+            _doc = oDOM;
+            return true;
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
+    /**
+     * Loads an InputStream into the DOM
+     *
+     * @return Boolean indicating success or failure
+     * @param oIS InputStream to load
+     */
+    public boolean load(InputStream oIS) {
+        try {
+            DocumentBuilderFactory oFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder oBuilder = oFactory.newDocumentBuilder();
+            Document oDOM = oBuilder.parse(oIS);
+
+            omNode = oDOM.getFirstChild();
+            _doc = oDOM;
+            return true;
+        } catch (Exception ex) {
+            logError(ex);
+            return false;
+        }
+    }
+
+    public boolean load(byte[] baXML) {
+        try {
+            return load(new GZIPInputStream(new ByteArrayInputStream(baXML)));
+        } catch (Exception ex) {
+            logError(ex);
+            return false;
+        }
+    }
+
+    /**
+     * Returns the value of a node or element
+     */
+    public String getValue() {
+        if (omNode.getNodeType() == Node.ATTRIBUTE_NODE) {
+            return omNode.getNodeValue();
+        } else {
+            return omNode.getFirstChild().getNodeValue();
+        }
+    }
+
+    /**
+     * Gets the Node Name
+     *
+     * @return the Node name of the current node
+     */
+    public String getName() {
+        return omNode.getNodeName();
+    }
+
+    /**
+     * Returns the value of a node or element as a string
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a string
+     */
+    public String getValue(String zXPath) {
+        try {
+            return getNode(zXPath).getValue();
+        } catch (Exception ex) {
+            return "";
+        }
+    }
+
+    /**
+     * Returns the value of a node or element as a string
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a string
+     */
+    public String getSQL(String zXPath) {
+        char first = zXPath.charAt(0);
+        switch (first) {
+            case ':':
+                return getString(zXPath.substring(1)).replaceAll("'", "''");
+            case 'i':
+                return "" + getInt(zXPath.substring(2));
+            default:
+                return "'" + getString(zXPath.substring(2)).replaceAll("'", "''") + "'";
+        }
+
+    }
+
+    /**
+     * Returns the value of a node or element as a string
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a string
+     */
+    public String getString(String zXPath) {
+        return getValue(zXPath);
+    }
+
+    /**
+     * Returns the value of a node or element as a long
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a long
+     */
+    public long getLong(String zXPath) {
+        try {
+            return Long.parseLong(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            return 0;
+        }
+    }
+
+    /**
+     * Returns the value of a node or element as an int
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as an int
+     */
+    public int getInt(String zXPath) {
+        try {
+            return Integer.parseInt(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            return 0;
+        }
+    }
+
+    public Integer getInteger(String zXPath) {
+        try {
+            return Integer.parseInt(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value of a node or element as a double
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a double
+     */
+    public double getDouble(String zXPath) {
+        try {
+            return Double.parseDouble(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            return 0.0;
+        }
+    }
+
+    public java.sql.Date getSQLDate(String zXPath) {
+        try {
+            return new java.sql.Date(getDate(zXPath).getTime());
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    public java.sql.Date getSQLDateTime(String zXPath) {
+        try {
+            return new java.sql.Date(getDateTime(zXPath).getTime());
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+   
+    /**
+     * Returns the value of a node or element as a double
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a double
+     */
+    public Date getDate(String zXPath) {
+        DateFormat df = new SimpleDateFormat(_DateFormat);
+        Date d = null;
+        try {
+            d = df.parse(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            try {
+                DateFormat altdf = new SimpleDateFormat(_AltDateFormat);
+                d = altdf.parse(getValue(zXPath).trim());
+            } catch (Exception ex1) {
+            }
+        }
+        return (d);
+    }
+
+    /**
+     * Returns the value of a node or element as a date
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a date
+     */
+    public Date getDateTime(String zXPath) {
+        DateFormat df = new SimpleDateFormat(_DateFormat + " HH:mm:ss");
+        Date d = null;
+        try {
+            d = df.parse(getValue(zXPath).trim());
+        } catch (Exception ex) {
+            try {
+                DateFormat altdf = new SimpleDateFormat(_AltDateFormat + " HH:mm:ss");
+                d = altdf.parse(getValue(zXPath).trim());
+            } catch (Exception ex1) {
+            }
+        }
+        return (d);
+    }
+
+    /**
+     * Returns the value of a node or element as a boolean
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as a boolean
+     */
+    public boolean getBoolean(String zXPath) {
+        String zVal = getValue(zXPath).toUpperCase();
+        return (zVal.equals("Y") || zVal.equals("YES") || zVal.equals("TRUE") || zVal.equals("1") || zVal.equals("ON"));
+    }
+
+    /**
+     * Returns the value of a node or element as either Y or N
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return The node value of the Node found as either Y or N
+     */
+    public String getYN(String zXPath) {
+        return (getBoolean(zXPath) ? "Y" : "N");
+    }
+
+    public int get10(String zXPath) {
+        return (getBoolean(zXPath) ? 1 : 0);
+    }
+
+    private Node getChildByTagName(String name) {
+        return getChildByTagName(omNode, name);
+    }
+
+    private Node getChildByTagName(Node oNode, String name) {
+        for (Node child = oNode.getFirstChild(); child != null; child = child.getNextSibling()) {
+            if (child.getNodeType() == Node.ELEMENT_NODE && name.equals(child.getNodeName())) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns an XMLHelper for a XPath
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return XMLHelper for a XPath
+     */
+    public XMLHelper getNode(String zXPath) {
+        Node oNode;
+        try {
+            if (zXPath.startsWith("@")) {
+                oNode = omNode.getAttributes().getNamedItem(zXPath.substring(1));
+            } else if (SimplePattern().matcher(zXPath).matches()) {
+                oNode = getChildByTagName(zXPath);
+            } else if (MediumPattern().matcher(zXPath).matches()) {
+                oNode = omNode;
+                Element e = (Element) oNode;
+                for (String part : zXPath.split("/")) {
+                    if (part.equals("..")) {
+                        oNode = oNode.getParentNode();
+                    } else if (!part.equals(".")) {
+                        oNode = getChildByTagName(oNode, part);
+                    }
+                    e = (Element) oNode;
+                }
+            } else {
+                oNode = (Node) Xpath().evaluate(zXPath, omNode, XPathConstants.NODE);
+            }
+            //oNode = XPathAPI.smeelectSingleNode(omNode, zXPath);
+            return new XMLHelper(oNode);
+        } catch (Exception ex) {
+            //logError(ex);
+            return null;
+        }
+    }
+
+    /**
+     * Returns an Array of XMLHelper objects for a XPath
+     *
+     * @param zXPath A valid XPath to find a node
+     * @return Array of XMLHelper object for a XPath
+     */
+    public XMLHelper[] getNodes(String zXPath) {
+        try {
+            NodeList oNodes = (NodeList) Xpath().evaluate(zXPath, omNode, XPathConstants.NODESET);
+            //NodeList oNodes = XPathAPI.selectNodeList(omNode, zXPath);
+            XMLHelper[] arrNodes = new XMLHelper[oNodes.getLength()];
+            for (int i = 0; i < oNodes.getLength(); i++) {
+                arrNodes[i] = new XMLHelper(oNodes.item(i));
+            }
+            return arrNodes;
+
+        } catch (Exception ex) {
+            logError(ex);
+            return null;
+        }
+    }
+
+    /**
+     * Sets a Nodes value
+     *
+     * @param zNodeName The name of the node to set
+     * @param oDOM The DOM to set
+     */
+    public void setNode(String zNodeName, XMLHelper oDOM) {
+        removeNode(zNodeName);
+
+        Node oNew = _Document().importNode(oDOM.getNode(zNodeName).omNode, true);
+        omNode.appendChild(oNew);
+    }
+
+    public void setNode(String zNodeName, Calendar oCal) {
+        setNode(zNodeName, oCal.getTime());
+    }
+
+    public void setNode(String zNodeName, Date oDate) {
+        DateFormat df = new SimpleDateFormat(_DateFormat);
+        setNode(zNodeName, df.format(oDate));
+    }
+
+    public void setNode(String zNodeName, Integer iValue) {
+        setNode(zNodeName, iValue.toString());
+    }
+
+    /**
+     * Sets a Nodes value
+     *
+     * @param zNodeName The name of the node to set
+     * @param zValue The value to set the node
+     */
+    public void setNode(String zNodeName, String zValue) {
+        Node oNode;
+        if (zNodeName.equals(".")) {
+            oNode = omNode;
+        } else if (zNodeName.startsWith("@")) {
+            setAttribute(zNodeName.substring(1), zValue);
+            return;
+        } else if (SimplePattern().matcher(zNodeName).matches()) {
+            oNode = getChildByTagName(zNodeName);
+        } else {
+            try {
+                oNode = (Node) Xpath().evaluate(zNodeName, omNode, XPathConstants.NODE);
+            } catch (Exception ex) {
+                oNode = null;
+            }
+        }
+        if (oNode == null) {
+            oNode = _Document().createElement(zNodeName);
+            oNode.appendChild(_Document().createTextNode(zValue == null ? "" : zValue));
+            omNode.appendChild(oNode);
+        } else {
+            oNode.setTextContent(zValue == null ? "" : zValue);
+        }
+    }
+
+    /**
+     * Transform the current DOM using XSLT to the OutputStream
+     *
+     * @param zXSL The location of the XSLT to use
+     * @param aParams Array of Parameters to pass to the XSLT processor
+     * @param oOut The OutputStream for the result
+     */
+    public void transform(String zXSL, String[] aParams, OutputStream oOut) {
+        try {
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            JARURIResolver oResolver = new JARURIResolver();
+            tFactory.setURIResolver(oResolver);
+            Transformer transformer = tFactory.newTransformer(oResolver.resolve(zXSL, null));
+            for (int i = 0; i < aParams.length; i++) {
+                transformer.setParameter("param" + (i + 1), aParams[i]);
+            }
+            transformer.transform(new DOMSource(omNode), new StreamResult(oOut));
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    public void transform(String zXSL, OutputStream oOut) {
+        transform(zXSL, new String[]{}, oOut);
+    }
+
+    public XMLHelper transform(String zXSL, HashMap<String, String> aParams) {
+        try {
+            //Get the directory from the file
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document oDOM = builder.newDocument();
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            JARURIResolver oResolver = new JARURIResolver();
+            tFactory.setURIResolver(oResolver);
+            Transformer transformer = tFactory.newTransformer(oResolver.resolve(zXSL, null));
+            for (String key : aParams.keySet()) {
+                transformer.setParameter(key, aParams.get(key));
+            }
+            //transformer.transform(new StreamSource(new ByteArrayInputStream(getXML().getBytes())), new DOMResult(oDOM));
+            transformer.transform(new DOMSource(omNode), new DOMResult(oDOM));
+            return new XMLHelper(oDOM);
+
+        } catch (Exception ex) {
+            logError(ex);
+            return null;
+        }
+    }
+
+    public void transform(String zXSL, HashMap<String, String> aParams, OutputStream oOut) {
+        try {
+            //Get the directory from the file
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document oDOM = builder.newDocument();
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            JARURIResolver oResolver = new JARURIResolver();
+            tFactory.setURIResolver(oResolver);
+            Transformer transformer = tFactory.newTransformer(oResolver.resolve(zXSL, null));
+            for (String key : aParams.keySet()) {
+                transformer.setParameter(key, aParams.get(key));
+            }
+            //transformer.transform(new StreamSource(new ByteArrayInputStream(getXML().getBytes())), new DOMResult(oDOM));
+            transformer.transform(new DOMSource(omNode), new StreamResult(oOut));
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    public void transform(String zXSL, HashMap<String, String> aParams, Writer oOut) {
+        try {
+            //Get the directory from the file
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document oDOM = builder.newDocument();
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            JARURIResolver oResolver = new JARURIResolver();
+            tFactory.setURIResolver(oResolver);
+            Transformer transformer = tFactory.newTransformer(oResolver.resolve(zXSL, null));
+            for (String key : aParams.keySet()) {
+                transformer.setParameter(key, aParams.get(key));
+            }
+            //transformer.transform(new StreamSource(new ByteArrayInputStream(getXML().getBytes())), new DOMResult(oDOM));
+            transformer.transform(new DOMSource(omNode), new StreamResult(oOut));
+        } catch (Exception ex) {
+            logError(ex);
+        }
+    }
+
+    public XMLHelper transform(String zXSL) {
+        return transform(zXSL, new HashMap<String, String>());
+    }
+
+    public XMLHelper transform(String zXSL, String[] aParams) {
+        HashMap<String, String> params = new HashMap<>();
+        for (int i = 0; i < aParams.length; i++) {
+            params.put("param" + (i + 1), aParams[i]);
+        }
+        return transform(zXSL, params);
+    }
+
+    public void transformPDF(String xslFile, OutputStream bOut) {
+        transformPDF(xslFile, "", bOut, null);
+    }
+
+    public void transformPDF(String xslFile, OutputStream bOut, String config) {
+        transformPDF(xslFile, "", bOut, config);
+    }
+
+    public void transformPDF(String xslFile, String zRootWeb, OutputStream bOut) {
+        transformPDF(xslFile, zRootWeb, bOut, null);
+    }
+    public void transformPDF(String xslFile, String zRootWeb, OutputStream bOut, String config) {
+        try {
+            
+            FopFactoryBuilder oBuilder = new FopFactoryBuilder(new File(".").toURI(), new JARResourceResolver());
+            JARURIResolver oResolver = new JARURIResolver();
+            
+            if (config != null) {
+                oBuilder.setConfiguration(new DefaultConfigurationBuilder().build(getClass().getResourceAsStream(config)));
+            }
+            FopFactory fopFactory = oBuilder.build();
+//            fopFactory.setURIResolver(oResolver);
+//            FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
+//            foUserAgent.setURIResolver(oResolver);
+            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, bOut);
+
+            // Setup Identity Transformer
+            TransformerFactory factory = TransformerFactory.newInstance();
+            factory.setURIResolver(oResolver);
+            Transformer transformer = factory.newTransformer(oResolver.resolve(xslFile, null)); // identity transformer
+            transformer.setParameter("root_web", zRootWeb);
+
+            // Setup input for XSLT transformation
+            Source src = new DOMSource(omNode);
+
+            // Resulting SAX events (the generated FO) must be piped through to FOP
+            Result res = new SAXResult(fop.getDefaultHandler());
+
+            // Start XSLT transformation and FOP processing
+            transformer.transform(src, res);
+//            return bOut.toByteArray();
+        } catch (Exception ex) {
+            logError(ex);
+            //return null;
+        }
+
+    }
+
+    public void transformPDFJar(String xslFile, OutputStream bOut) {
+        transformPDFJar(xslFile, null, bOut);
+    }
+
+    public void transformPDFJar(String xslFile, HashMap<String, String> aParams, OutputStream bOut) {
+        try {
+            FopFactoryBuilder oBuilder = new FopFactoryBuilder(new File(".").toURI(), new JARResourceResolver());
+            FopFactory fopFactory = oBuilder.build();
+//            FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
+            JARURIResolver oResolver = new JARURIResolver();
+//            foUserAgent.setURIResolver(oResolver);
+            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, bOut);
+
+            // Setup Identity Transformer
+            TransformerFactory factory = TransformerFactory.newInstance();
+            factory.setURIResolver(oResolver);
+            Transformer transformer = factory.newTransformer(oResolver.resolve(xslFile, null)); // identity transformer
+            if (aParams != null) {
+                for (String key : aParams.keySet()) {
+                    transformer.setParameter(key, aParams.get(key));
+                }
+            }
+
+            // Setup input for XSLT transformation
+            ByteArrayInputStream oBytes = new ByteArrayInputStream(getXML().getBytes("UTF-8"));
+            Source src = new StreamSource(oBytes);
+            //Source src = new DOMSource(omNode);
+
+            // Resulting SAX events (the generated FO) must be piped through to FOP
+            Result res = new SAXResult(fop.getDefaultHandler());
+
+            // Start XSLT transformation and FOP processing
+            transformer.transform(src, res);
+//            return bOut.toByteArray();
+        } catch (Exception ex) {
+            logError(ex);
+            //return null;
+        }
+
+    }
+
+    /**
+     * Transform the current DOM using XSLT to a Writer object
+     *
+     * @param zXSL The location of the XSLT to use
+     * @param aParams Array of parameters to pass to the XSLT Processor
+     * @param oOut The Writer for the result
+     */
+    public void transform(String zXSL, String[] aParams, Writer oOut) {
+        try {
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            JARURIResolver oResolver = new JARURIResolver();
+            tFactory.setURIResolver(oResolver);
+            Transformer transformer = tFactory.newTransformer(oResolver.resolve(zXSL, null));
+            for (int i = 0; i < aParams.length; i++) {
+                transformer.setParameter("param" + (i + 1), aParams[i]);
+            }
+            transformer.transform(new DOMSource(omNode), new StreamResult(oOut));
+        } catch (TransformerException ex) {
+            logError(ex);
+        }
+    }
+
+    public void transform(String zXSL, Writer oOut) {
+        transform(zXSL, new String[]{}, oOut);
+    }
+
+    @Override
+    public String toString() {
+        StringWriter oString = new StringWriter();
+        serializeNode(omNode, oString, true);
+        return oString.toString();
+    }
+
+    public String getJSON() throws Exception {
+        StringWriter stringOut = new StringWriter();
+        getJSON(stringOut);
+        return (stringOut.toString());
+    }
+
+    public void getJSON(Writer oOut) throws Exception {
+        oOut.write("{");
+        getJSON((Node) _Document().getFirstChild(), false, oOut);
+        oOut.write("}");
+    }
+
+    private void getJSON(Node oNode, boolean isArray, Writer oOut) throws Exception {
+        String zName = oNode.getNodeName();
+        if (zName.equals("#text")) {
+            zName = "$";
+        }
+        if (!isArray) {
+            oOut.write(_QUOTE + zName + _QUOTE + ":");
+        }
+        //String zValue = (oNode.getNodeType() == omNode.ATTRIBUTE_NODE) ? omNode.getNodeValue() : omNode.getFirstChild().getNodeValue();
+        if (isJSONArray(oNode.getChildNodes())) {
+            oOut.write("[");
+            getJSON(oNode.getChildNodes(), true, oOut);
+            oOut.write("]");
+        } else if (oNode.getNodeType() == Node.ATTRIBUTE_NODE) {
+            oOut.write(getJSONValue(oNode.getNodeValue()));
+        } else if (!oNode.hasChildNodes() && !oNode.hasAttributes()) {
+            if (oNode.getNodeValue() == null) {
+                oOut.write("null");
+            } else {
+                oOut.write(getJSONValue(oNode.getNodeValue()));
+            }
+        } else if (!oNode.hasAttributes() && oNode.getChildNodes().getLength() == 1 && !oNode.getFirstChild().hasChildNodes()) {
+            oOut.write(getJSONValue(oNode.getFirstChild().getNodeValue()));
+        } else {
+            oOut.write("{");
+            getJSON(oNode.getAttributes(), oOut);
+            if (oNode.getAttributes().getLength() > 0 && oNode.getChildNodes().getLength() > 0) {
+                oOut.write(",");
+            }
+            getJSON(oNode.getChildNodes(), false, oOut);
+            oOut.write("}");
+        }
+    }
+
+    private void getJSON(NodeList oNodeList, boolean isArray, Writer oOut) throws Exception {
+        for (int i = 0; i < oNodeList.getLength(); i++) {
+            Node oNode = oNodeList.item(i);
+            //if (oNode.getNodeType() != oNode.TEXT_NODE)
+            //{
+            if (i > 0) {
+                oOut.write(",");
+            }
+            getJSON(oNode, isArray, oOut);
+            //}
+//            if (!oNode.getNodeValue().equals("\n"))
+//            {
+//                if (i > 0) oOut.write(",");
+//                toJSON(oNode, oOut);
+//            }
+        }
+    }
+
+    private void getJSON(NamedNodeMap oNodeMap, Writer oOut) throws Exception {
+        for (int i = 0; i < oNodeMap.getLength(); i++) {
+            Node oNode = oNodeMap.item(i);
+            if (i > 0) {
+                oOut.write(",");
+            }
+            getJSON(oNode, false, oOut);
+//            if (i > 0)
+//                oOut.write(", ");
+//            oOut.write(_QUOTE + oNode.getNodeName() + _QUOTE + " : ");
+//            oOut.write(_QUOTE + oNode.getNodeValue() + _QUOTE);
+        }
+    }
+
+    private String getJSONValue(String zValue) {
+        if (zValue == null) {
+            return "null";
+        }
+        zValue = zValue.trim();
+        if (DatePattern().matcher(zValue).matches()) {
+            DateFormat df = new SimpleDateFormat(_DateFormat + ((zValue.length() > 11) ? " HH:mm:ss" : ""));
+            Date matchDate = new Date();
+            try {
+                matchDate = df.parse(zValue);
+            } catch (Exception ex) {
+            }
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(matchDate);
+            //String ret = "\"\\/Date(" + matchDate.getTime() + ")\\/\"";
+            String ret = "new Date(" + cal.get(Calendar.YEAR) + "," + cal.get(Calendar.MONTH) + "," + cal.get(Calendar.DATE);
+            if (zValue.length() > 11) {
+                ret += "," + cal.get(Calendar.HOUR_OF_DAY) + "," + cal.get(Calendar.MINUTE) + "," + cal.get(Calendar.SECOND);
+            }
+            ret += ")";
+            return ret;
+        } else if (zValue.length() <= 10) {
+            try {
+                return Integer.toString(Integer.parseInt(zValue));
+            } catch (Exception ex) {
+            }
+            try {
+                return Double.toString(Double.parseDouble(zValue));
+            } catch (Exception ex) {
+            }
+        }
+        return _QUOTE + zValue.replace("\\", "\\\\").replace("\"", "\\\"") + _QUOTE;
+    }
+
+    private boolean isJSONArray(NodeList oNodeList) {
+        if (oNodeList.getLength() < 1 || (oNodeList.getLength() == 1 && !(oNodeList.item(0).getNodeName() + "s").equals(oNodeList.item(0).getParentNode().getNodeName()))) {
+            return (false);
+        }
+        String zName = oNodeList.item(0).getNodeName();
+        for (int i = 0; i < oNodeList.getLength(); i++) {
+            if (!oNodeList.item(i).getNodeName().equals(zName)) {
+                return (false);
+            }
+        }
+        return (true);
+    }
+
+    public int nodeCount(String zXPath) {
+        try {
+            NodeList oNodes = (NodeList) Xpath().evaluate(zXPath, omNode, XPathConstants.NODESET);
+            //NodeList oNodes = XPathAPI.selectNodeList(omNode, zXPath);
+            return (oNodes.getLength());
+        } catch (Exception ex) {
+            return 0;
+        }
+    }
+
+    public void loadCSV(InputStream is) throws Exception {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        String line;
+        int row = 0;
+        XMLHelper oRows = this.appendNode("rows");
+        XMLHelper oRow = null;
+        ArrayList<String> aCols = new ArrayList<>();
+        Pattern regex = Pattern.compile("(?:^|,)\"?((?<=\")[^\"]*|[^,\"]*)\"?(?=,|$)");
+        while ((line = reader.readLine()) != null) {
+            Matcher m = regex.matcher(line);
+            int col = 0;
+            if (row > 0) {
+                oRow = oRows.appendNode("row");
+            }
+            while (m.find()) {
+                String match = m.group(1) == null ? m.group(2) : m.group(1);
+                if (row == 0) {
+                    String val = match.toLowerCase().replace(" ", "_").replace("+", "plus");
+                    aCols.add((val.length() == 0) ? "col" + col : val);
+                } else {
+                    oRow.appendNode(aCols.get(col), match);
+                }
+                col++;
+            }
+            row++;
+        }
+    }
+
+    public String getCSV(String nodePath) {
+        boolean bFirst = true;
+        StringBuilder sb = new StringBuilder();
+        for (XMLHelper oNode : getNodes(nodePath)) {
+            if (!bFirst) {
+                sb.append(',');
+            }
+            sb.append(oNode.getString("."));
+            bFirst = false;
+        }
+        return sb.toString();
+    }
+
+    public ArrayList<String> parseCSVLine(String line) throws Exception {
+        ArrayList<String> list = new ArrayList<>();
+        Matcher m = CSVPattern().matcher(line);
+        while (m.find()) {
+            String match = m.group(1) == null ? m.group(2) : m.group(1);
+            list.add(match);
+        }
+        return list;
+    }
+
+    public ArrayList<String> parseTSVLine(String line) throws Exception {
+        ArrayList<String> list = new ArrayList<>();
+        Matcher m = TSVPattern().matcher(line);
+        while (m.find()) {
+            String match = m.group(1) == null ? m.group(2) : m.group(1);
+            list.add(match);
+        }
+        return list;
+    }
+
+    /**
+     * Test Harness
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) throws Exception {
+        // Test simple Load
+        XMLHelper oDOM = new XMLHelper();
+        //oDOM.load("C:\\tmp\\tz.xml");
+        //System.out.println(oDOM.getXML());
+
+//        oDOM.load("/tmp/test.xml");
+//        XMLHelper opdf = oDOM.transform("/home/paul/java/ecommerce/vaccines.co.uk/src/java/fop/contract_FLU.xsl", new String[] {});
+//        opdf.saveAs("/tmp/test.fo");
+//        System.out.println("dsadasd");
+        // Test creating a DOM by handing and manipulating it
+        oDOM.createStandardRequest("test_type", "PYL38997", "CIMS");
+        oDOM.appendNode("test", "value");
+        System.out.println("test:" + oDOM.getValue("test"));
+        System.out.println("@type:" + oDOM.getValue("@type"));
+        oDOM.removeNode("test");
+        System.out.println(oDOM.getRootXML());
+
+        try {
+            System.out.println(oDOM.getJSON());
+        } catch (Exception ex) {
+        }
+        // More manipulation
+        oDOM.appendNode("test", "value");
+        oDOM.setNode("test", "new Value");
+        oDOM = oDOM.appendNode("groups");
+        for (int i = 0; i < 10; i++) {
+            oDOM.appendNode("group").appendAttribute("id", Integer.toString(i));        // Test getNodes
+        }
+        XMLHelper[] oNodes = oDOM.getNodes("//group");
+        for (XMLHelper oNode : oNodes) {
+            System.out.println(oNode.getXML());
+        }
+        System.out.println(oDOM.getRootXML());
+        try {
+            System.out.println(oDOM.getJSON());
+        } catch (Exception ex) {
+        }
+
+        // Test appending an entirely new DOM
+        XMLHelper oNew = new XMLHelper("new");
+        oNew.appendNode("test", "40213423");
+        oDOM.appendNode(oNew);
+        System.out.println(oDOM.getRootXML());
+
+        // Test appending a Nodelist
+        oNew.appendNode(oNodes);
+        System.out.println(oNew.getRootXML());
+
+        System.out.println(oDOM.omNode.getOwnerDocument().getFirstChild().getChildNodes().getLength());
+        System.out.println(oDOM.omNode.getOwnerDocument().getElementsByTagName("group").getLength());
+        System.out.println(oDOM.getParent().getNode("group").getXML());
+
+        XMLHelper o = new XMLHelper("response");
+        o.appendXPathNode("customer/@id", "1");
+        o.appendXPathNode("customer/name/first", "john");
+        o.appendXPathNode("customer/name/last", "doe");
+        o.appendNode("date", "01-jan-2005");
+        o.appendNode("empty_date", "");
+        System.out.println(o.getDate("date"));
+        System.out.println(o.getDate("empty_date"));
+        System.out.println(o.getRootXML());
+        System.out.println(o.omNode.getChildNodes().getLength());
+        System.out.println("Inner : " + o.getInnerXML());
+//        FileWriter oFile;
+//        try
+//        {
+//            oFile = new FileWriter("/Users/paul/test.xml");
+//            o.serializeNode(oFile);
+//            oFile.close();
+//        } catch (IOException ex)
+//        {
+//            ex.printStackTrace();
+//        }
+        XMLHelper newHelper = new XMLHelper();
+        newHelper.load("C:\\dev\\vaccines\\Web\\xml\\Deal.xml");
+        try {
+            System.out.println(newHelper.getJSON());
+        } catch (Exception ex) {
+        }
+    }
+}

+ 131 - 0
src/xsl/scopeschema.xsl

@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:s="http://schemas.microsoft.com/xbox/instrumentation/1"
+    exclude-result-prefixes="s">
+    <xsl:output method="xml" indent="no"/>
+  <xsl:param name="title_id" select="'LNHD_7406ADEA'"/>
+  <xsl:param name="date" select="'2015-01-01'"/>
+  <xsl:variable name="year" select="substring($date,1,4)"/>
+  <xsl:variable name="month" select="substring($date,6,2)"/>
+  <xsl:key name="event" match="Events/Event" use="concat(../../Provider/Name, '|', @Name)" />
+  <xsl:variable name="b_schemas" select="/EtxManifests/Instrumentation"/>
+  <xsl:template match="/">
+      <xsl:apply-templates select="/EtxManifests/EtxManifest[Provider/Name = $title_id]"/>
+  </xsl:template>
+
+<xsl:template match="EtxManifest">
+    <events>
+        <xsl:for-each select="Events/Event[generate-id(.)=generate-id(key('event',concat($title_id, '|', @Name))[last()])]">
+            <xsl:variable name="partb" select="PartB"/>
+            <xsl:variable name="b_schema" select="$b_schemas/SchemaPart[@Abbreviation=$partb/@Abbreviation and @Version=$partb/@Version]"/>
+            <event name="{@Name}" abbrev="{$partb/@Abbreviation}" path="https://cosmos15.osdinfra.net/cosmos/IEBKS.Partner/shares/IEBKS.Partner/processed/Soho/{$title_id}/Events/{$year}/{$month}/{@Name}_{$date}.ss">
+                <scols>
+<!--                    <Column>
+                        <Name>ProcessDate</Name>
+                        <Type>DateTime</Type>
+                    </Column>
+                    <Column>
+                        <Name>EventName</Name>
+                        <Type>string</Type>
+                    </Column>-->
+                    <xsl:call-template name="field">
+                        <xsl:with-param name="node" select="$b_schema/Fields/Field"/>
+                        <xsl:with-param name="schema" select="'b'"/>
+                    </xsl:call-template>
+                    <xsl:call-template name="field">
+                        <xsl:with-param name="node" select="PartC/Fields/Field"/>
+                        <xsl:with-param name="schema" select="'c'"/>
+                    </xsl:call-template>
+<!--                    <Column>
+                        <Name>SessionId</Name>
+                        <Type>Guid</Type>
+                    </Column>
+                    <Column>
+                        <Name>DateLogged</Name>
+                        <Type>DateTime</Type>
+                    </Column>-->
+                </scols>
+            </event>
+        </xsl:for-each>
+<!--        <event name="TelemetryErrors">
+            <scols>
+                <Column>
+                    <Name>ProcessDate</Name>
+                    <Type>DateTime</Type>
+                </Column>
+                <Column>
+                    <Name>EventName</Name>
+                    <Type>string</Type>
+                </Column>
+                <Column>
+                    <Name>ErrorType</Name>
+                    <Type>long</Type>
+                </Column>
+                <Column>
+                    <Name>ErrorMessage</Name>
+                    <Type>string</Type>
+                </Column>
+                <Column>
+                    <Name>ErrorData</Name>
+                    <Type>string</Type>
+                    <max>3990</max>
+                </Column>
+            </scols>
+        </event>
+        <event name="AllEvents">
+            <scols>
+                <Column>
+                    <Name>ProcessDate</Name>
+                    <Type>DateTime</Type>
+                </Column>
+                <Column>
+                    <Name>EventName</Name>
+                    <Type>string</Type>
+                </Column>
+                <Column>
+                    <Name>UserId</Name>
+                    <Type>string</Type>
+                </Column>
+                <Column>
+                    <Name>PlayerSessionId</Name>
+                    <Type>string</Type>
+                </Column>
+                <Column>
+                    <Name>SessionId</Name>
+                    <Type>Guid</Type>
+                </Column>
+                <Column>
+                    <Name>DateLogged</Name>
+                    <Type>DateTime</Type>
+                </Column>
+            </scols>
+        </event>-->
+    </events>
+</xsl:template>    
+
+<xsl:template name="field">
+    <xsl:param name="node"/>
+    <xsl:param name="schema"/>
+        <xsl:for-each select="$node">
+            <Column>
+                <Name schema="{$schema}"><xsl:value-of select="@Name"/></Name>
+                <xsl:variable name="type">
+                    <xsl:choose>
+                        <xsl:when test="contains(@Type, 'Int')">long</xsl:when>
+                        <xsl:when test="contains(@Type, 'String')">string</xsl:when>
+                        <xsl:when test="@Type='GUID'">Guid</xsl:when>
+                        <xsl:when test="@Type='Float' or @Type='Double'">double</xsl:when>
+                         <xsl:when test="@Type='Boolean'">bool</xsl:when>
+                       <xsl:otherwise>
+                            <xsl:value-of select="@Type"/>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </xsl:variable>
+                <Type><xsl:value-of select="$type"/></Type>
+         </Column>
+        </xsl:for-each>
+
+</xsl:template>
+
+
+</xsl:stylesheet>