Add StripQualifier task and associated tests. Minor cleanup of ToLower.
diff --git a/ant_customizations.jar b/ant_customizations.jar
index 850a4c7..89c3db6 100644
--- a/ant_customizations.jar
+++ b/ant_customizations.jar
Binary files differ
diff --git a/ant_customizations/antbuild.xml b/ant_customizations/antbuild.xml
index 53df3e9..fa5507d 100644
--- a/ant_customizations/antbuild.xml
+++ b/ant_customizations/antbuild.xml
@@ -42,7 +42,7 @@
         <property name="classes.dir" value="${output.dir}/classes"/>
         <property name="custom.jar"  value="ant_customizations.jar"/>
         <property name="custom.lib"  value="${output.dir}/${custom.jar}"/>
-        
+
         <echo message="publish.dir                              ='${publish.dir}'"/>
         <echo message="output.dir                               ='${output.dir}'"/>
         <echo message="src.dir                                  ='${src.dir}'"/>
@@ -93,24 +93,26 @@
     <target name="publish" depends="init, pub_init, archive-old">
         <copy file="${custom.lib}" todir="${publish.dir}"/>
     </target>
-    
+
     <!-- TESTING TARGETS -->
-    <target name="test" depends="test-init, test-version-class, test-selectbundle, test-cleanRevision"/>
+    <target name="test" depends="test-init, test-version-class, test-selectbundle, test-cleanRevision, test-stripQualifier"/>
 
     <target name="test-init" depends="init">
-        <property name="custom.tasks.lib" value="${publish.dir}/ant_customizations.jar"/>
-        <property name="custom.echo.task.class" value="org.eclipse.persistence.buildtools.ant.taskdefs.Say"/>
-        <property name="custom.selectbundle.task.class" value="org.eclipse.persistence.buildtools.ant.taskdefs.SelectBundle"/>
-        <property name="custom.cleanrev.task.class" value="org.eclipse.persistence.buildtools.ant.taskdefs.CleanRevision"/>
+        <property name="custom.tasks.lib"                 value="${publish.dir}/ant_customizations.jar"/>
+        <property name="custom.echo.task.class"           value="org.eclipse.persistence.buildtools.ant.taskdefs.Say"/>
+        <property name="custom.selectbundle.task.class"   value="org.eclipse.persistence.buildtools.ant.taskdefs.SelectBundle"/>
+        <property name="custom.cleanrev.task.class"       value="org.eclipse.persistence.buildtools.ant.taskdefs.CleanRevision"/>
+        <property name="custom.stripqualifier.task.class" value="org.eclipse.persistence.buildtools.ant.taskdefs.StripQualifier"/>
 
         <echo message="custom.tasks.lib = '${custom.tasks.lib}'"/>
         <available file="${custom.tasks.lib}" property="antcustomizations.lib.exist"/>
         <fail message="Ant customizations file not found!" unless="antcustomizations.lib.exist"/>
 
-        <taskdef name="say"          classname="${custom.echo.task.class}"         classpath="${custom.tasks.lib}"/>
-        <taskdef name="selectbundle" classname="${custom.selectbundle.task.class}" classpath="${custom.tasks.lib}"/>
-        <taskdef name="cleanRevision" classname="${custom.cleanrev.task.class}"    classpath="${custom.tasks.lib}"/>
-        
+        <taskdef name="say"            classname="${custom.echo.task.class}"           classpath="${custom.tasks.lib}"/>
+        <taskdef name="selectbundle"   classname="${custom.selectbundle.task.class}"   classpath="${custom.tasks.lib}"/>
+        <taskdef name="cleanRevision"  classname="${custom.cleanrev.task.class}"       classpath="${custom.tasks.lib}"/>
+        <taskdef name="stripQualifier" classname="${custom.stripqualifier.task.class}" classpath="${custom.tasks.lib}"/>
+
         <say message=" First test is passed. Customizations found and 'say' works!" if="antcustomizations.lib.exist"/>
     </target>
 
@@ -138,16 +140,16 @@
         <property name="bnd.criteria"     value="[0.0.350, 0.1.0)"/>
         <property name="bnd.property"     value="selected.bnd.jar"/>
         <property name="bnd.property2"    value="selected.bnd.lib"/>
-        
+
         <property name="xmlbind.prefix"     value="javax.xml.bind"/>
         <property name="xmlbind.criteria"   value="[2.0, 3.0)"/>
         <property name="xmlbind.property"   value="selected.xmlbind.jar"/>
-        
+
         <property name="ant.prefix"           value="org.apache.ant"/>
         <property name="ant.criteria"         value="[1.7, 1.8)"/>
         <property name="ant.property"         value="selected.ant.jar"/>
         <property name="ant.version.property" value="selected.ant.version"/>
-        
+
         <property name="jpa.prefix"      value="javax.persistence"/>
         <property name="jpa.criteria"    value="[1.0, 2.2)"/>
         <property name="jpa.property"    value="selected.jpa.jar"/>
@@ -179,7 +181,7 @@
         <say message="selected file: '${selected.bnd.jar}'" if="${bnd.property}"/>
         <say message="Bnd (${bnd.prefix}) bundle not found in '${bnd.search.dir}'!" unless="${bnd.property}"/>
         <say message="If not found bdn.property was overwritten by second search in '..'"/>
-        
+
         <say message=" "/>
         <say message="Test includepath flag using bnd..."/>
         <selectbundle
@@ -192,7 +194,7 @@
         />
         <say message="selected file: '${selected.bnd.lib}'" if="${bnd.property2}"/>
         <say message="Bnd (${bnd.prefix}) bundle not found in '${bnd.search.dir}'!" unless="${bnd.property2}"/>
-        
+
         <say message=" "/>
         <say message="Test finding ${xmlbind.prefix} (using default separator)..."/>
         <selectbundle
@@ -273,7 +275,7 @@
         <property name="svn.base.urlpath"    value="//${svn.server.name}/svnroot/rt/org.eclipse.persistence"/>
         <property name="svn.base.url"        value="${svn.r.protocol}${svn.base.urlpath}"/>
         <property name="svn.branch.url"      value="${svn.base.url}/${branch.dir}"/>
-        
+
         <exec outputproperty="svn.revision"
             failonerror="false"
             failifexecutionfails="false"
@@ -291,4 +293,44 @@
         <say message="a:svn.revision = '${svn.revision}'"/>
     </target>
 
+    <target name="test-stripQualifier" depends="test-init">
+        <say message=" "/>
+        <say message="Test removing qualifier from '1.2.0.test'..."/>
+        <stripQualifier
+            input="1.2.0.test"
+            property="120test.value"
+        />
+        <say message="    Result: '${120test.value}'" if="120test.value"/>
+        <say message="    Result: Property '120test.value' not set (error)." unless="120test.value"/>
+
+        <say message=" "/>
+        <say message="Test removing qualifier from '2'..."/>
+        <stripQualifier
+            input="2"
+            property="2test.value"
+        />
+        <say message="    Result: '${2test.value}'" if="2test.value"/>
+        <say message="    Result: Property '2test.value' not set (error)." unless="2test.value"/>
+
+        <say message=" "/>
+        <say message="Test removing qualifier from '4.1'..."/>
+        <stripQualifier
+            input="4.1"
+            property="41test.value"
+        />
+        <say message="    Result: '${41test.value}'" if="41test.value"/>
+        <say message="    Result: Property '41test.value' not set (error)." unless="41test.value"/>
+
+        <say message=" "/>
+        <say message="Test removing qualifier from '5.3.1'..."/>
+        <stripQualifier
+            input="5.3.1"
+            property="531test.value"
+        />
+        <say message="    Result: '${531test.value}'" if="531test.value"/>
+        <say message="    Result: Property '531test.value' not set (error)." unless="531test.value"/>
+
+    </target>
+
+
 </project>
diff --git a/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/StripQualifier.java b/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/StripQualifier.java
new file mode 100644
index 0000000..64112b6
--- /dev/null
+++ b/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/StripQualifier.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * StripQualifier
+ *    input    - "version" to reduce to 3-part equivilent
+ *    property - Property to store the results in
+ *
+ * Contributors:
+ *     egwin - initial conception and implementation
+ */
+
+package org.eclipse.persistence.buildtools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.eclipse.persistence.buildtools.helper.Version;
+//import org.eclipse.persistence.buildtools.helper.VersionException;
+
+public class StripQualifier extends Task {
+    private String input    = null;    // Version String to reduce to 3-part version
+    private String property = null;    // Name of Property to set with stripped value
+    private Version version = null;    // local: storage for version to strip
+
+    public void execute() throws BuildException {
+        if (input == null) {
+            throw new BuildException("'input' attribute must be set.", getLocation());
+        }
+        if (property == null) {
+            throw new BuildException("'property' attribute must be set.", getLocation());
+        }
+        if (property == "") {
+            throw new BuildException("'property' cannot be an empty string.", getLocation());
+        }
+        if ( input.startsWith("${") || input.startsWith("@{") || input == "" ) {
+            // If input empty or unexpanded then set value of property to 'NA'
+            log("StripQualifier finished.  Input empty or search failed! original value was '" + input + "'.", Project.MSG_VERBOSE);
+            throw new BuildException("'input' is empty, or a property value cannot be expanded.", getLocation());
+        }
+        else {
+            // put result into property - overwrites previous value! Not safe for <parallel> tasks
+            //try {
+                version = new Version(input);
+            //} catch ( VersionException e){
+            //    log("stripQualifier: Exception detected -> " + e, Project.MSG_VERBOSE);
+            //}
+           	getProject().setProperty( property, version.get3PartStr() );
+            log("StripQualifier finished. Old string of '" + input + "' set to '" + version.get3PartStr() + "' in property '" + property + "'.", Project.MSG_VERBOSE);
+        }
+    }
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+}
diff --git a/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/ToLower.java b/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/ToLower.java
index a6cffeb..b060feb 100644
--- a/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/ToLower.java
+++ b/ant_customizations/src/org/eclipse/persistence/buildtools/ant/taskdefs/ToLower.java
@@ -1,61 +1,58 @@
-/*******************************************************************************

- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.

- * This program and the accompanying materials are made available under the

- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

- * which accompanies this distribution.

- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

- * and the Eclipse Distribution License is available at

- * http://www.eclipse.org/org/documents/edl-v10.php.

- *

- * SelectBundle

- *   basename     (bnd, org.eclipse.equinox) : required

- *   criterion    OSGi version selection criteria [1.0,2.0) : required

- *   separator    separator used between basename and version in filename (such as - or _) : defaults to _

- *   property     propety to set : required

- *   includepath  boolean flag, if set will include path and filename in "property" : defaults to 'false'

- *   versiononly  boolean flag, if set will only set full version of bundle in "property" : defaults to 'false'

- *

- * Contributors:

- *     egwin - initial conception and implementation

- */

-

-package org.eclipse.persistence.buildtools.ant.taskdefs;

-

-import org.apache.tools.ant.BuildException;

-import org.apache.tools.ant.Project;

-import org.apache.tools.ant.Task;

-

-public class ToLower extends Task {

-    private String input = null;

-    private String property = null;

-    

-    public void execute() throws BuildException {

-        if (input == null) {

-            throw new BuildException("'input' attribute must be set.", getLocation());

-        }

-        if (property == null) {

-            throw new BuildException("'property' attribute must be set.", getLocation());

-        }

-        if (property == "") {

-            throw new BuildException("'property' cannot be an empty string.", getLocation());

-        }

-        if ( input.startsWith("${") || input.startsWith("@{") || input == "" ) {

-            // If input empty or unexpanded then set value of property to 'NA'

-            log("ToLower Finished.  Input empty or search failed! original value was '" + input + "'.", Project.MSG_VERBOSE);  

-            throw new BuildException("'input' is empty, or a property value cannot be expanded.", getLocation());

-        }

-        else {            

-            // put result into property - NB overwrites previous value! Not safe for <parallel> tasks

-            getProject().setProperty( property, input.toLowerCase());

-            log("ToLower Finished. Old string of '" + input + "' set to '" + input.toLowerCase() + "' in property '" + property + "'.", Project.MSG_VERBOSE);  

-        }

-    }

-    

-    public void setInput(String input) {

-        this.input = input;

-    }

-

-    public void setProperty(String property) {

-        this.property = property;

-    }

-}

+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * ToLower
+ *     input    - String to convert to lowercase
+ *     property - Property to store the results in
+ *
+ * Contributors:
+ *     egwin - initial conception and implementation
+ *     egwin - minor cleanup to documentation and formating
+ */
+
+package org.eclipse.persistence.buildtools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+public class ToLower extends Task {
+    private String input = null;
+    private String property = null;
+
+    public void execute() throws BuildException {
+        if (input == null) {
+            throw new BuildException("'input' attribute must be set.", getLocation());
+        }
+        if (property == null) {
+            throw new BuildException("'property' attribute must be set.", getLocation());
+        }
+        if (property == "") {
+            throw new BuildException("'property' cannot be an empty string.", getLocation());
+        }
+        if ( input.startsWith("${") || input.startsWith("@{") || input == "" ) {
+            // If input empty or unexpanded then set value of property to 'NA'
+            log("ToLower Finished.  Input empty or search failed! original value was '" + input + "'.", Project.MSG_VERBOSE);
+            throw new BuildException("'input' is empty, or a property value cannot be expanded.", getLocation());
+        }
+        else {
+            // put result into property - NB overwrites previous value! Not safe for <parallel> tasks
+            getProject().setProperty( property, input.toLowerCase());
+            log("ToLower Finished. Old string of '" + input + "' set to '" + input.toLowerCase() + "' in property '" + property + "'.", Project.MSG_VERBOSE);
+        }
+    }
+
+    public void setInput(String input) {
+        this.input = input;
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+}
diff --git a/ant_customizations/src/org/eclipse/persistence/buildtools/helper/Version.java b/ant_customizations/src/org/eclipse/persistence/buildtools/helper/Version.java
index cac0932..2521e0d 100644
--- a/ant_customizations/src/org/eclipse/persistence/buildtools/helper/Version.java
+++ b/ant_customizations/src/org/eclipse/persistence/buildtools/helper/Version.java
@@ -1,249 +1,253 @@
-/*******************************************************************************

- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.

- * This program and the accompanying materials are made available under the

- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0

- * which accompanies this distribution.

- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html

- * and the Eclipse Distribution License is available at

- * http://www.eclipse.org/org/documents/edl-v10.php.

- *

- * Version

- *   class defines OSGi-like behavior to a version object

- *   it has an identifier (Major.Minor.Micro.Qualifier) and can compare itself to others

- *   it can report its identifier, and its identifier can be set

- *

- * Contributors:

- *     egwin - initial conception and implementation

- */

-

-package org.eclipse.persistence.buildtools.helper;

-

-import java.lang.NumberFormatException;

-

-import org.eclipse.persistence.buildtools.helper.VersionException;;

-

-public class Version {

-    private String  identifier = "0.0";

-    private Integer major = 0;

-    private Integer minor = 0;

-    private Integer micro = 0;

-    private String  qualifier = "";

-

-    private int[] indexList = {0,0,0};               //holds the indexes of the "."s in the identifier string.

-

-    // helper

-    private String validateIdentifier(String identifier) throws VersionException{

-        String validated=identifier;

-        boolean error=false;

-

-        // clear leading whitespace

-        while ( validated.startsWith(" ") || validated.startsWith("\t") ) 

-            validated=validated.substring(1);

-        // clear trailing whitespace

-        while ( validated.endsWith(" ") || validated.endsWith("\t") ) 

-            validated=validated.substring(0,validated.length() - 1);

-        

-        if ( validated.startsWith(".") ) {

-            throw new VersionException("Initial version tokenizer found (.): Invalid version string '" + validated + "'.");

-        }

-        else {

-            if( validated.endsWith(".") ) {

-                throw new VersionException("Terminating version tokenizer found (.): Invalid version string '" + validated + "'.");

-            }

-            else {

-                int index = 0;

-                int subindex = 0;

-                int count = 0;

-                int maxindex = validated.lastIndexOf(".");

-                while( !error && ( (subindex = validated.substring(index).indexOf(".")) >0 || index<maxindex )) {

-                    if(count>2 && subindex>0)

-                        throw new VersionException("Maximum (4) tokens exceeded: Invalid version string '" + validated + "'.");

-                    else {

-                        index += subindex;

-                        indexList[count] = index;

-                        index++;                //increment to point to char after found '.'

-                        count++;

-                    }

-                }

-            }

-        }

-        return validated;

-    }

-

-    // setter

-    private void setMajor(Integer major) {

-        this.major = major;

-    }

-    private void setMinor(Integer minor) {

-        this.minor = minor;

-    }

-    private void setMicro(Integer micro) {

-        this.micro = micro;

-    }

-    private void setQualifier(String qualifier) {

-        this.qualifier = qualifier;

-    }

-

-    private void setAll(String identifier) throws VersionException{

-        // assumes basic validation completed

-        try {

-            if( identifier != "" ){

-                if( indexList[0] > 0 ) {

-                    setMajor(Integer.valueOf( identifier.substring(0, indexList[0])));

-                    if( indexList[1] > 0 ) {

-                        setMinor(Integer.valueOf( identifier.substring(indexList[0]+1, indexList[1])));

-                        if( indexList[2] > 0 ) {

-                            setMicro(Integer.valueOf( identifier.substring(indexList[1]+1, indexList[2])));

-                            setQualifier(identifier.substring(indexList[2]+1));

-                        }

-                        else

-                            setMicro(Integer.valueOf( identifier.substring(indexList[1]+1)));

-                    }

-                    else

-                        setMinor(Integer.valueOf( identifier.substring(indexList[0]+1) ));

-                }

-                else

-                    setMajor(Integer.valueOf(identifier));

-            }

-        } catch ( NumberFormatException e){

-            throw new VersionException("Major.Minor.Micro tokens expected to be numeric. One or more is invalid. " + e.getMessage() + " in \"" + identifier + "\".", e);

-        }

-        String validIdentifier = getMajorStr() + "." + getMinorStr() + "." + getMicroStr();

-        if(getQualifier() != null && getQualifier() != "" ) {

-            validIdentifier+= "." + getQualifier();

-        }

-        this.identifier = validIdentifier;

-    }

-

-    // Public methods

-    //     constructors

-    public Version() {

-    }

-    public Version(String identifier) {

-        setIdentifier(identifier);

-    }

-

-    // getters

-    public Integer getMajorInt() {

-        return this.major;

-    }

-    public Integer getMinorInt() {

-        return this.minor;

-    }

-    public Integer getMicroInt() {

-        return this.micro;

-    }

-    public String getMajorStr() {

-        return this.major.toString();

-    }

-    public String getMinorStr() {

-        return this.minor.toString();

-    }

-    public String getMicroStr() {

-        return this.micro.toString();

-    }

-    public String getQualifier() {

-        return this.qualifier;

-    }

-    public String getIdentifier() {

-        return this.identifier;

-    }

-

-    // setters

-    public void setIdentifier(String identifier) {

-        setAll(validateIdentifier(identifier));

-    }

-

-    // Compare Versions

-    public boolean gt( Version comp ) {

-        boolean result=false;

-

-        if(this.major > comp.getMajorInt()) result = true;

-        else if ( (this.major == comp.getMajorInt()) && (this.minor > comp.getMinorInt()) ) result = true;

-             else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro > comp.getMicroInt()) ) result=true;

-                  else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) > 0) ) result=true;

-

-        return result;

-    }

-    public boolean lt( Version comp ) {

-        boolean result=false;

-

-        if(this.major < comp.getMajorInt()) result = true;

-        else if ( (this.major == comp.getMajorInt()) && (this.minor < comp.getMinorInt()) ) result = true;

-             else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro < comp.getMicroInt()) ) result=true;

-                  else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) < 0) ) result=true;

-

-        return result;

-    }

-    public boolean eq( Version comp ) {

-        boolean result=false;

-

-        if( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) == 0) ) {

-            result = true;

-        }

-        return result;

-    }

-    public boolean ge( Version comp ) {

-        boolean result=false;

-

-        if( (this.gt(comp) || this.eq(comp) ) ) result = true;

-        return result;

-    }

-    public boolean le( Version comp ) {

-        boolean result=false;

-

-        if( (this.lt(comp) || this.eq(comp) ) ) result = true;

-        return result;

-    }

-

-    public boolean empty() {

-        boolean result=false;

-

-        if( (this.major == 0) && (this.minor == 0) && (this.micro == 0) && (this.qualifier.compareTo("") == 0) ) {

-            result = true;

-        }

-        return result;

-    }

-

-    // Compare version strings

-    //public boolean gt( String comp ) {

-    //    boolean result=false;

-    //

-    //    if(this.identifier.compareTo(comp) > 0) {

-    //        result = true;

-    //    }

-    //    return result;

-    //}

-    //public boolean lt( String comp ) {

-    //    boolean result=false;

-    //

-    //    if(this.identifier.compareTo(comp) < 0) {

-    //        result = true;

-    //    }

-    //    return result;

-    //}

-    //public boolean ge( String comp ) {

-    //    boolean result=false;

-    //

-    //    if(this.identifier.compareTo(comp) >= 0) {

-    //        result = true;

-    //    }

-    //    return result;

-    //}

-    //public boolean le( String comp ) {

-    //    boolean result=false;

-    //

-    //    if(this.identifier.compareTo(comp) <= 0) {

-    //        result = true;

-    //    }

-    //    return result;

-    //}

-    //public boolean eq( String comp ) {

-    //    boolean result=false;

-    //

-    //    if(this.identifier.equals(comp)) {

-    //        result = true;

-    //    }

-    //    return result;

-    //}

-}

+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Version
+ *   class defines OSGi-like behavior to a version object
+ *   it has an identifier (Major.Minor.Micro.Qualifier) and can compare itself to others
+ *   it can report its identifier, and its identifier can be set
+ *
+ * Contributors:
+ *     egwin - initial conception and implementation
+ */
+
+package org.eclipse.persistence.buildtools.helper;
+
+import java.lang.NumberFormatException;
+
+import org.eclipse.persistence.buildtools.helper.VersionException;;
+
+public class Version {
+    private String  identifier = "0.0";
+    private Integer major = 0;
+    private Integer minor = 0;
+    private Integer micro = 0;
+    private String  qualifier = "";
+
+    private int[] indexList = {0,0,0};               //holds the indexes of the "."s in the identifier string.
+
+    // helper
+    private String validateIdentifier(String identifier) throws VersionException{
+        String validated=identifier;
+        boolean error=false;
+
+        // clear leading whitespace
+        while ( validated.startsWith(" ") || validated.startsWith("\t") )
+            validated=validated.substring(1);
+        // clear trailing whitespace
+        while ( validated.endsWith(" ") || validated.endsWith("\t") )
+            validated=validated.substring(0,validated.length() - 1);
+
+        if ( validated.startsWith(".") ) {
+            throw new VersionException("Initial version tokenizer found (.): Invalid version string '" + validated + "'.");
+        }
+        else {
+            if( validated.endsWith(".") ) {
+                throw new VersionException("Terminating version tokenizer found (.): Invalid version string '" + validated + "'.");
+            }
+            else {
+                int index = 0;
+                int subindex = 0;
+                int count = 0;
+                int maxindex = validated.lastIndexOf(".");
+                while( !error && ( (subindex = validated.substring(index).indexOf(".")) >0 || index<maxindex )) {
+                    if(count>2 && subindex>0)
+                        throw new VersionException("Maximum (4) tokens exceeded: Invalid version string '" + validated + "'.");
+                    else {
+                        index += subindex;
+                        indexList[count] = index;
+                        index++;                //increment to point to char after found '.'
+                        count++;
+                    }
+                }
+            }
+        }
+        return validated;
+    }
+
+    // setter
+    private void setMajor(Integer major) {
+        this.major = major;
+    }
+    private void setMinor(Integer minor) {
+        this.minor = minor;
+    }
+    private void setMicro(Integer micro) {
+        this.micro = micro;
+    }
+    private void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    private void setAll(String identifier) throws VersionException{
+        // assumes basic validation completed
+        try {
+            if( identifier != "" ){
+                if( indexList[0] > 0 ) {
+                    setMajor(Integer.valueOf( identifier.substring(0, indexList[0])));
+                    if( indexList[1] > 0 ) {
+                        setMinor(Integer.valueOf( identifier.substring(indexList[0]+1, indexList[1])));
+                        if( indexList[2] > 0 ) {
+                            setMicro(Integer.valueOf( identifier.substring(indexList[1]+1, indexList[2])));
+                            setQualifier(identifier.substring(indexList[2]+1));
+                        }
+                        else
+                            setMicro(Integer.valueOf( identifier.substring(indexList[1]+1)));
+                    }
+                    else
+                        setMinor(Integer.valueOf( identifier.substring(indexList[0]+1) ));
+                }
+                else
+                    setMajor(Integer.valueOf(identifier));
+            }
+        } catch ( NumberFormatException e){
+            throw new VersionException("Major.Minor.Micro tokens expected to be numeric. One or more is invalid. " + e.getMessage() + " in \"" + identifier + "\".", e);
+        }
+        String validIdentifier = get3PartStr();
+        if(getQualifier() != null && getQualifier() != "" ) {
+            validIdentifier+= "." + getQualifier();
+        }
+        this.identifier = validIdentifier;
+    }
+
+    // Public methods
+    //     constructors
+    public Version() {
+    }
+    public Version(String identifier) {
+        setIdentifier(identifier);
+    }
+
+    // getters
+    public Integer getMajorInt() {
+        return this.major;
+    }
+    public Integer getMinorInt() {
+        return this.minor;
+    }
+    // Micro also referred to as "bugfix" token of version
+    public Integer getMicroInt() {
+        return this.micro;
+    }
+    public String getMajorStr() {
+        return this.major.toString();
+    }
+    public String getMinorStr() {
+        return this.minor.toString();
+    }
+    public String getMicroStr() {
+        return this.micro.toString();
+    }
+    public String get3PartStr() {
+        return getMajorStr() + "." + getMinorStr() + "." + getMicroStr();
+    }
+    public String getQualifier() {
+        return this.qualifier;
+    }
+    public String getIdentifier() {
+        return this.identifier;
+    }
+
+    // setters
+    public void setIdentifier(String identifier) {
+        setAll(validateIdentifier(identifier));
+    }
+
+    // Compare Versions
+    public boolean gt( Version comp ) {
+        boolean result=false;
+
+        if(this.major > comp.getMajorInt()) result = true;
+        else if ( (this.major == comp.getMajorInt()) && (this.minor > comp.getMinorInt()) ) result = true;
+             else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro > comp.getMicroInt()) ) result=true;
+                  else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) > 0) ) result=true;
+
+        return result;
+    }
+    public boolean lt( Version comp ) {
+        boolean result=false;
+
+        if(this.major < comp.getMajorInt()) result = true;
+        else if ( (this.major == comp.getMajorInt()) && (this.minor < comp.getMinorInt()) ) result = true;
+             else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro < comp.getMicroInt()) ) result=true;
+                  else if ( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) < 0) ) result=true;
+
+        return result;
+    }
+    public boolean eq( Version comp ) {
+        boolean result=false;
+
+        if( (this.major == comp.getMajorInt()) && (this.minor == comp.getMinorInt()) && (this.micro == comp.getMicroInt()) && (this.qualifier.compareTo(comp.getQualifier()) == 0) ) {
+            result = true;
+        }
+        return result;
+    }
+    public boolean ge( Version comp ) {
+        boolean result=false;
+
+        if( (this.gt(comp) || this.eq(comp) ) ) result = true;
+        return result;
+    }
+    public boolean le( Version comp ) {
+        boolean result=false;
+
+        if( (this.lt(comp) || this.eq(comp) ) ) result = true;
+        return result;
+    }
+
+    public boolean empty() {
+        boolean result=false;
+
+        if( (this.major == 0) && (this.minor == 0) && (this.micro == 0) && (this.qualifier.compareTo("") == 0) ) {
+            result = true;
+        }
+        return result;
+    }
+
+    // Compare version strings
+    //public boolean gt( String comp ) {
+    //    boolean result=false;
+    //
+    //    if(this.identifier.compareTo(comp) > 0) {
+    //        result = true;
+    //    }
+    //    return result;
+    //}
+    //public boolean lt( String comp ) {
+    //    boolean result=false;
+    //
+    //    if(this.identifier.compareTo(comp) < 0) {
+    //        result = true;
+    //    }
+    //    return result;
+    //}
+    //public boolean ge( String comp ) {
+    //    boolean result=false;
+    //
+    //    if(this.identifier.compareTo(comp) >= 0) {
+    //        result = true;
+    //    }
+    //    return result;
+    //}
+    //public boolean le( String comp ) {
+    //    boolean result=false;
+    //
+    //    if(this.identifier.compareTo(comp) <= 0) {
+    //        result = true;
+    //    }
+    //    return result;
+    //}
+    //public boolean eq( String comp ) {
+    //    boolean result=false;
+    //
+    //    if(this.identifier.equals(comp)) {
+    //        result = true;
+    //    }
+    //    return result;
+    //}
+}