initial checkin
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c594b9c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,40 @@
+target/
+eclipse_config/
+.settings/
+thirdparty/
+bin/
+*.class
+
+**/target/
+**/.metadata/
+
+**/emf-gen/**/.gitignore
+**/src-gen/**/.gitignore
+**/git.properties
+**/*.java._trace
+**/*.log
+**/*.log.properties
+
+**/bin/
+**/build/
+*.class
+*.ctrl
+**/Debug/
+.DS_Store
+*.ear
+*.war
+
+**/*.actionbin
+**/*.blipbin
+**/*.chartbin
+**/*.cubebin
+**/*.datatypebin
+**/*.dtobin
+**/*.entitybin
+**/*.servicebin
+**/*.tablebin
+**/*.uibin
+**/*.uisemanticbin
+**/*.xtendbin
+**/*.xtextbin
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..1f575eb
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/.gitignore b/bundles/.gitignore
new file mode 100644
index 0000000..834befa
--- /dev/null
+++ b/bundles/.gitignore
@@ -0,0 +1,3 @@
+/src
+/.settings
+/target
diff --git a/bundles/.project b/bundles/.project
new file mode 100644
index 0000000..fd2d9df
--- /dev/null
+++ b/bundles/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>bundles</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.business.tests/.classpath b/bundles/org.eclipse.uomo.business.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.business.tests/.gitignore b/bundles/org.eclipse.uomo.business.tests/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.business.tests/.project b/bundles/org.eclipse.uomo.business.tests/.project
new file mode 100644
index 0000000..86f27d0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.business.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.business.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.business.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..6bff12f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.business.tests
+Bundle-SymbolicName: org.eclipse.uomo.business.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.business;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.junit
diff --git a/bundles/org.eclipse.uomo.business.tests/build.properties b/bundles/org.eclipse.uomo.business.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.business.tests/pom.xml b/bundles/org.eclipse.uomo.business.tests/pom.xml
new file mode 100644
index 0000000..24a5f08
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/pom.xml
@@ -0,0 +1,13 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.business.tests</artifactId>
+	<name>UOMo Business Tests</name>
+	<packaging>eclipse-test-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/Calculations.java b/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/Calculations.java
new file mode 100644
index 0000000..1b96b94
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/Calculations.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+
+/**
+ * @author Werner Keil
+ *
+ */
+public class Calculations {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		println("Test");
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/SmokeTests.java b/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/SmokeTests.java
new file mode 100644
index 0000000..81c7dfa
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business.tests/src/org/eclipse/uomo/business/money/SmokeTests.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil and others - initial API and implementation
+ */
+
+package org.eclipse.uomo.business.money;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.uomo.business.internal.CurrencyUnit;
+import org.eclipse.uomo.business.internal.ExchangeRate;
+import org.eclipse.uomo.business.internal.ExchangeRateType;
+import org.eclipse.uomo.business.internal.MonetaryAmount;
+import org.eclipse.uomo.business.types.IMoney;
+
+import java.math.RoundingMode;
+import java.util.Locale;
+
+import org.junit.Test;
+import java.util.logging.Logger;
+
+public class SmokeTests {
+	private static final Logger LOGGER = Logger.getLogger(SmokeTests.class.getName());
+
+	private static final ExchangeRateType RATE_TYPE = ExchangeRateType
+			.of("EZB");
+
+	@Test
+	public void testCreateAmounts() {
+		// Creating one
+		CurrencyUnit currency = MoneyUnit.of("CHF");
+		MonetaryAmount amount1 = MoneyAmount.of(1.0d, currency);
+		MonetaryAmount amount2 = MoneyAmount.of(1.0d, currency);
+		MonetaryAmount amount3 = amount1.add(amount2);
+		LOGGER.fine(amount1 + " + " + amount2 + " = " + amount3);
+		assertEquals("ISO-4217", currency.getNamespace());
+		assertEquals(1.0d, amount1.doubleValue(), 0);
+		assertEquals(1.0d, amount2.doubleValue(), 0);
+		assertEquals(2.0d, amount3.doubleValue(), 0);
+	}
+
+	@Test
+	public void testCreateIMoney() {
+		// Creating one
+		IMoney amount1 = MoneyAmount.of("CHF", 1.0d);
+		IMoney amount2 = MoneyAmount.of("CHF", 1.0d);
+		IMoney amount3 = (IMoney) amount1.add(amount2);
+		LOGGER.fine(amount1 + " + " + amount2 + " = " + amount3);
+		assertEquals(1.0d, amount1.value().doubleValue(), 0);
+		assertEquals(1.0d, amount2.value().doubleValue(), 0);
+		assertEquals(2.0d, amount3.value().doubleValue(), 0);
+	}
+}
+
diff --git a/bundles/org.eclipse.uomo.business/.classpath b/bundles/org.eclipse.uomo.business/.classpath
new file mode 100644
index 0000000..27c73cf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="lib" path="lib/icu4j-50_1_1.jar"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.business/.gitignore b/bundles/org.eclipse.uomo.business/.gitignore
new file mode 100644
index 0000000..e7da900
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/.gitignore
@@ -0,0 +1,3 @@
+/target
+/.settings
+/target
diff --git a/bundles/org.eclipse.uomo.business/.project b/bundles/org.eclipse.uomo.business/.project
new file mode 100644
index 0000000..0101862
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/.project
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.business</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.business/.springBeans b/bundles/org.eclipse.uomo.business/.springBeans
new file mode 100644
index 0000000..4dff647
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.3.2.201003220227-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.business/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.business/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..727044e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.business
+Bundle-SymbolicName: org.eclipse.uomo.business
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Require-Bundle: org.eclipse.uomo.core;bundle-version="0.6.0",
+ org.eclipse.uomo.units;bundle-version="0.5.0",
+ org.unitsofmeasurement.unit-api;bundle-version="0.6.1"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Import-Package: org.eclipse.osgi.util;version="1.1.0"
+Bundle-ClassPath: .,
+ lib/icu4j-50_1_1.jar
diff --git a/bundles/org.eclipse.uomo.business/build.properties b/bundles/org.eclipse.uomo.business/build.properties
new file mode 100644
index 0000000..01949b5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/build.properties
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+bin.includes = META-INF/,\
+               .,\
+               lib/icu4j-50_1_1.jar
diff --git a/bundles/org.eclipse.uomo.business/lib/icu4j-50_1_1.jar b/bundles/org.eclipse.uomo.business/lib/icu4j-50_1_1.jar
new file mode 100644
index 0000000..4994a5c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/lib/icu4j-50_1_1.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.business/pom.xml b/bundles/org.eclipse.uomo.business/pom.xml
new file mode 100644
index 0000000..15115d7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.business</artifactId>
+	<name>UOMo Business</name>
+	<packaging>eclipse-plugin</packaging>
+	<!-- ======================================================= -->
+	<!-- Build Settings -->
+	<!-- ======================================================= -->
+	<build>
+		<plugins>
+			<!-- ======================================================= -->
+			<!-- Compilation -->
+			<!-- ======================================================= -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>${maven.compilerPlugin.version}</version>
+				<configuration>
+					<source>${project.build.javaVersion}</source>
+					<target>${project.build.javaVersion}</target>
+					<encoding>${project.build.sourceEncoding}</encoding>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/CurrencyUnit.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/CurrencyUnit.java
new file mode 100644
index 0000000..5b51043
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/CurrencyUnit.java
@@ -0,0 +1,111 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+/**
+ * A unit of currency.
+ * <p>
+ * This interface represents a unit of currency such as the British Pound, Euro, US
+ * Dollar, Bitcoin or other.
+ * <p>
+ * Currencies can be distinguished within separate arbitrary currency name
+ * spaces, whereas as {@link #ISO_NAMESPACE} will be the the most commonly used
+ * one, similar to {@link java.util.Currency}.
+ * 
+ * @version 0.4
+ * @author Werner Keil
+ * 
+ * @see <a
+ *      href="https://en.wikipedia.org/wiki/Currency">Wikipedia: Currency</a>
+ * @deprecated this is a stub, replacing it by JSR 354 as soon as it's in MavenCentral!
+ */
+public interface CurrencyUnit {
+
+	/**
+	 * Defines the name space for the currency code. If the CurrencyUnit is an
+	 * instance of <type>java.util.Currency</type> this method returns
+	 * 'ISO-4217', whereas for other currency schemes, e.g. virtual currencies
+	 * or internal legacy currencies different values are possible.
+	 * 
+	 * @return the name space of the currency, never null.
+	 */
+	public String getNamespace();
+
+	/**
+	 * Gets the currency code, the effective code depends on the currency and
+	 * the name space. It is possible that the two currency may have the same
+	 * code, but different name spaces.
+	 * <p>
+	 * Each currency is uniquely identified within its name space by this code.
+	 * <p>
+	 * This method matches the API of <type>java.util.Currency</type>.
+	 * 
+	 * @return the currency code. Instances of <type>java.util.Currency</type>
+	 *         return the three letter ISO-4217 or equivalent currency code,
+	 *         never null.
+	 */
+	public String getCurrencyCode();
+
+	/**
+	 * Gets a numeric currency code. within the ISO-4217 name space, this equals
+	 * to the ISO numeric code. In other currency name spaces this number may be
+	 * different, or even undefined (-1).
+	 * <p>
+	 * The numeric code is an optional alternative to the standard currency
+	 * code.
+	 * <p>
+	 * This method matches the API of <type>java.util.Currency</type>.
+	 * 
+	 * @return the numeric currency code
+	 */
+	public int getNumericCode();
+
+	/**
+	 * Gets the number of fractional digits typically used by this currency.
+	 * <p>
+	 * Different currencies have different numbers of fractional digits by
+	 * default. * For example, 'GBP' has 2 fractional digits, but 'JPY' has
+	 * zero. * virtual currencies or those with no applicable fractional are indicated by -1. *
+	 * <p>
+	 * This method matches the API of <type>java.util.Currency</type>.
+	 * 
+	 * @return the fractional digits, from 0 to 9 (normally 0, 2 or 3), or -1
+	 *         for pseudo-currencies.
+	 * 
+	 */
+	public int getDefaultFractionDigits();
+
+	/**
+	 * Checks if this is a currency that has a legal tender.
+	 * 
+	 * @return true if this currency has a legal tender.
+	 */
+	public boolean isLegalTender();
+
+	/**
+	 * Checks if this is a virtual currency, such as Bitcoin or Linden Dollar.
+	 * 
+	 * @return true if this is a virtual currency.
+	 */
+	public boolean isVirtual();
+
+	/**
+	 * Get the timestamp from when this currency instance is valid.<br/>
+	 * This is useful for historic currencies.
+	 * 
+	 * @return the UTC timestamp from where this instance is valid. If not
+	 *         defined {@code null} should be returned.
+	 */
+	public Long getValidFrom();
+
+	/**
+	 * Get the timestamp until when this currency instance is valid.<br/>
+	 * This is useful for historic currencies.
+	 * 
+	 * @return the UTC timestamp until when this instance is valid. If not
+	 *         defined {@code null} should be returned.
+	 */
+	public Long getValidUntil();
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRate.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRate.java
new file mode 100644
index 0000000..08beb5b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRate.java
@@ -0,0 +1,145 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+import java.util.Enumeration;
+
+import com.ibm.icu.util.Currency;
+
+/**
+ * This interface models a exchange rate between two currencies.
+ * 
+ * @author Werner Keil
+ * @version 0.2.2
+ * @deprecated stub
+ */
+public interface ExchangeRate {
+
+	/**
+	 * Access the type of exchange rate.
+	 * 
+	 * @return the type of this rate, never null.
+	 */
+	public ExchangeRateType getExchangeRateType();
+
+	/**
+	 * Get the source currency.
+	 * 
+	 * @return the source currency.
+	 */
+	public Currency getSource();
+
+	/**
+	 * Get the target currency.
+	 * 
+	 * @return the target currency.
+	 */
+	public Currency getTarget();
+
+	/**
+	 * Access the rate's factor.
+	 * 
+	 * @return the factor for this exchange rate.
+	 */
+	public Number getFactor();
+
+	/**
+	 * Returns the UTC timestamp defining from what date/time this rate is
+	 * valid.
+	 * 
+	 * @return The UTC timestamp of the rate, defining valid from, or
+	 *         {@code null}.
+	 */
+	public Long getValidFrom();
+
+	/**
+	 * Get the data validity timestamp of this rate in milliseconds. This can be
+	 * useful, when a rate in a system only should be used within some specified
+	 * time.
+	 * 
+	 * @return the duration of validity in milliseconds, or {@code null} if no
+	 *         validity constraints apply.
+	 */
+	public Long getValidUntil();
+
+	/**
+	 * Allows to check if a rate is still valid according to its data validity
+	 * timestamp.
+	 * 
+	 * @see #getValidUntil()
+	 * @return true, if the rate is valid for use.
+	 */
+	public boolean isValid();
+
+	/**
+	 * Get the provider of this rate. The provider of a rate can have different
+	 * contexts in different usage scenarios, such as the service type or the
+	 * stock exchange.
+	 * 
+	 * @return the provider, or {code null}.
+	 */
+	public String getProvider();
+
+	/**
+	 * Access the chain of exchange rates.
+	 * 
+	 * @return the chain of rates, in case of a derived rate, this may be
+	 *         several instances. For a direct exchange rate, this equals to
+	 *         <code>new ConversionRate[]{this}</code>.
+	 */
+	public ExchangeRate[] getExchangeRateChain();
+
+	/**
+	 * Allows to evaluate if this exchange rate is a derived exchange rate.
+	 * Derived exchange rates are defined by an ordered list of subconversions
+	 * with intermediate steps, whereas a direct conversion is possible in one
+	 * steps.
+	 * 
+	 * @return true, if the exchange rate is derived.
+	 */
+	public boolean isDerived();
+
+	/**
+	 * Checks if a conversion is an identity.
+	 * 
+	 * @param sourceCurrency
+	 *            The source currency
+	 * @param targetCurrency
+	 *            The target currency
+	 * @return true, if the conversion is linear.
+	 * @throws CurrencyConversionException
+	 *             if conversion failed, or the required data is not available.
+	 */
+	public boolean isIdentity();
+
+	/**
+	 * Access additional attributes of this currency instance. This allows to
+	 * add additional codes or extended information by SPI providers. For
+	 * instance there are ISO currency codes existing that may represented by
+	 * different country specific currencies. The detailed country can be added
+	 * as an attribute here.
+	 * 
+	 * @param key
+	 *            The attribute's key, never null.
+	 * @return the according attribute value, or null.
+	 */
+	public <T> T getAttribute(String key, Class<T> type);
+
+	/**
+	 * Access the extended attributes defined.
+	 * 
+	 * @return the attribute key available, never null.
+	 */
+	public Enumeration<String> getAttributeKeys();
+
+	/**
+	 * Access the type of an attribute.
+	 * 
+	 * @param key
+	 *            The attribute key
+	 * @return the attribute's value class, or null.
+	 */
+	public Class<?> getAttributeType(String key);
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRateType.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRateType.java
new file mode 100644
index 0000000..bc7e2b0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/ExchangeRateType.java
@@ -0,0 +1,139 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * This class models the type of a given exchange rate as immutable value type.
+ * Basically the types possible are determined by the concrete use cases and
+ * implementations. Typical use cases is that exchange rates for different
+ * credit card systems or debit/credit may differ. This class allows to
+ * distinguish these rates.
+ * 
+ * @author Werner Keil
+ * @deprecated stub
+ */
+public final class ExchangeRateType implements Serializable,
+Comparable<ExchangeRateType> {
+
+	/** The id of this type. */
+	private final String id;
+	/** The cache of types. */
+	private static final Map<String, ExchangeRateType> CACHED_INSTANCES = new ConcurrentHashMap<String, ExchangeRateType>();
+
+	/**
+	 * Creates a new instance.
+	 * 
+	 * @param id
+	 *            The rate identifier.
+	 * @return The new rate type.
+	 */
+	public static ExchangeRateType of(String id) {
+		if (id == null) {
+			throw new IllegalArgumentException("id required.");
+		}
+		ExchangeRateType instance = CACHED_INSTANCES.get(id);
+		if (instance == null) {
+			instance = new ExchangeRateType(id);
+			CACHED_INSTANCES.put(id, instance);
+		}
+		return instance;
+	}
+
+	/**
+	 * Get all cached rate types.
+	 * 
+	 * @return all cached rate types.
+	 */
+	public static Collection<ExchangeRateType> getTypes() {
+		return CACHED_INSTANCES.values();
+	}
+
+	/**
+	 * Constructs a new instance of an ExchangeRateType..
+	 * 
+	 * @param id
+	 *            The id of this type instance, never null.
+	 */
+	public ExchangeRateType(String id) {
+		if (id == null) {
+			throw new IllegalArgumentException("Id must not be null.");
+		}
+		this.id = id;
+	}
+
+	/**
+	 * Get the identifier of this instance.
+	 * 
+	 * @return The identifier, never null.
+	 */
+	public String getId() {
+		return this.id;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ExchangeRateType other = (ExchangeRateType) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return "ExchangeRateType [id=" + id + "]";
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Comparable#compareTo(java.lang.Object)
+	 */
+	@Override
+	public int compareTo(ExchangeRateType o) {
+		if (o == null) {
+			return -1;
+		}
+		int compare = id.compareTo(o.id);
+		return compare;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Localizable.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Localizable.java
new file mode 100644
index 0000000..b1db040
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Localizable.java
@@ -0,0 +1,27 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+import java.util.Locale;
+
+/**
+ * This interface is implemented by types that are localiable for display.
+ * 
+ * @TODO check if this class can be moved to {@code java.util} or at least "format" module.
+ * 
+ * @author Werner Keil
+ * @deprecated this is a stub, replacing it by JSR 354 as soon as it's in MavenCentral!
+ */
+public interface Localizable {
+
+	/**
+	 * Access a display name for the item, that can be shown for display.
+	 * 
+	 * @param locale
+	 *            The {@link Locale} to be used.
+	 * @return the formatted display name
+	 */
+	public String getDisplayName(Locale locale);
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Messages.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Messages.java
new file mode 100644
index 0000000..e1e2853
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/Messages.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = Messages.class.getPackage()
+			.getName() + ".messages"; //$NON-NLS-1$
+	public static String CurrencyConverter_exchangeRate_not_set;
+	public static String CurrencyConverter_toString;
+	public static String Market_invalid_code;
+	public static String StockTicker_invalid_symbol;
+	public static String StockTicker_invalid_market;
+	public static String StockTicker_invalid_country;
+	public static String StockTicker_missing_symbol;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryAmount.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryAmount.java
new file mode 100644
index 0000000..8b8920d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryAmount.java
@@ -0,0 +1,620 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+import java.math.BigDecimal;
+
+/**
+ * Interface defining a monetary amount. The effective internal representation
+ * of an amount may vary depending on the implementation used. Nevertheless
+ * basically an amount provides a functionality similar to {@link BigDecimal}.
+ * <p>
+ * Since {@link Number} is not an interface, this type is not extending
+ * {@link Number}.
+ * 
+ * @version 0.4.2
+ * @author Werner Keil
+ * @deprecated this is a stub, replacing it by JSR 354 as soon as it's in MavenCentral!
+ */
+public interface MonetaryAmount {
+
+	/**
+	 * Gets the amount's currency.
+	 * 
+	 * @return the currency, never {@code null}
+	 */
+	public CurrencyUnit getCurrency();
+
+	// -------------------- calculation methods
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is the absolute value of
+	 * this {@code MonetaryAmount}, and whose scale is
+	 * {@code this.getgetScale()}.
+	 * 
+	 * @return {@code abs(this)}
+	 */
+	public MonetaryAmount abs();
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this +
+	 * augend)}, and whose scale is {@code max(this.getScale(),
+	 * augend.getScale())}.
+	 * 
+	 * @param augend
+	 *            value to be added to this {@code MonetaryAmount}.
+	 * @return {@code this + augend}
+	 */
+	public MonetaryAmount add(MonetaryAmount augend);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this +
+	 * augend)}, and whose scale is {@code max(this.getScale(),
+	 * augend.getScale())}.
+	 * 
+	 * @param augend
+	 *            value to be added to this {@code MonetaryAmount}.
+	 * @return {@code this + augend}
+	 */
+	public MonetaryAmount add(Number augend);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this /
+	 * divisor)}, and whose preferred scale is {@code (this.getScale() -
+	 * divisor.getScale())}; if the exact quotient cannot be represented
+	 * (because it has a non-terminating decimal expansion) an
+	 * {@code ArithmeticException} is thrown.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @throws ArithmeticException
+	 *             if the exact quotient does not have a terminating decimal
+	 *             expansion
+	 * @return {@code this / divisor}
+	 */
+	public MonetaryAmount divide(MonetaryAmount divisor);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this /
+	 * divisor)}, and whose preferred scale is {@code (this.getScale() -
+	 * divisor.getScale())}; if the exact quotient cannot be represented
+	 * (because it has a non-terminating decimal expansion) an
+	 * {@code ArithmeticException} is thrown.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @throws ArithmeticException
+	 *             if the exact quotient does not have a terminating decimal
+	 *             expansion
+	 * @return {@code this / divisor}
+	 */
+	public MonetaryAmount divide(Number divisor);
+
+	/**
+	 * Returns a two-element {@code MonetaryAmount} array containing the result
+	 * of {@code divideToIntegralValue} followed by the result of
+	 * {@code remainder} on the two operands.
+	 * 
+	 * <p>
+	 * Note that if both the integer quotient and remainder are needed, this
+	 * method is faster than using the {@code divideToIntegralValue} and
+	 * {@code remainder} methods separately because the division need only be
+	 * carried out once.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided,
+	 *            and the remainder computed.
+	 * @return a two element {@code MonetaryAmount} array: the quotient (the
+	 *         result of {@code divideToIntegralValue}) is the initial element
+	 *         and the remainder is the final element.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 * @see #divideToIntegralValue(MonetaryAmount)
+	 * @see #remainder(MonetaryAmount)
+	 */
+	public MonetaryAmount[] divideAndRemainder(MonetaryAmount divisor);
+
+	/**
+	 * Returns a two-element {@code MonetaryAmount} array containing the result
+	 * of {@code divideToIntegralValue} followed by the result of
+	 * {@code remainder} on the two operands.
+	 * 
+	 * <p>
+	 * Note that if both the integer quotient and remainder are needed, this
+	 * method is faster than using the {@code divideToIntegralValue} and
+	 * {@code remainder} methods separately because the division need only be
+	 * carried out once.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided,
+	 *            and the remainder computed.
+	 * @return a two element {@code MonetaryAmount} array: the quotient (the
+	 *         result of {@code divideToIntegralValue}) is the initial element
+	 *         and the remainder is the final element.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 * @see #divideToIntegralValue(MonetaryAmount)
+	 * @see #remainder(MonetaryAmount)
+	 */
+	public MonetaryAmount[] divideAndRemainder(Number divisor);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is the integer part of the
+	 * quotient {@code (this / divisor)} rounded down. The preferred scale of
+	 * the result is {@code (this.getScale() -
+	 * divisor.getScale())}.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @return The integer part of {@code this / divisor}.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 */
+	public MonetaryAmount divideToIntegralValue(MonetaryAmount divisor);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is the integer part of the
+	 * quotient {@code (this / divisor)} rounded down. The preferred scale of
+	 * the result is {@code (this.getScale() -
+	 * divisor.getScale())}.
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @return The integer part of {@code this / divisor}.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 */
+	public MonetaryAmount divideToIntegralValue(Number divisor);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is <tt>(this &times;
+	 * multiplicand)</tt>, and whose scale is {@code (this.getScale() +
+	 * multiplicand.getScale())}.
+	 * 
+	 * @param multiplicand
+	 *            value to be multiplied by this {@code MonetaryAmount}.
+	 * @return {@code this * multiplicand}
+	 */
+	public MonetaryAmount multiply(MonetaryAmount multiplicand);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is <tt>(this &times;
+	 * multiplicand)</tt>, and whose scale is {@code (this.getScale() +
+	 * multiplicand.getScale())}.
+	 * 
+	 * @param multiplicand
+	 *            value to be multiplied by this {@code MonetaryAmount}.
+	 * @return {@code this * multiplicand}
+	 */
+	public MonetaryAmount multiply(Number multiplicand);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (-this)}, and
+	 * whose scale is {@code this.getScale()}.
+	 * 
+	 * @return {@code -this}.
+	 */
+	public MonetaryAmount negate();
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (+this)}, and
+	 * whose scale is {@code this.getScale()}.
+	 * 
+	 * <p>
+	 * This method, which simply returns this {@code MonetaryAmount} is included
+	 * for symmetry with the unary minus method {@link #negate()}.
+	 * 
+	 * @return {@code this}.
+	 * @see #negate()
+	 */
+	public MonetaryAmount plus();
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this -
+	 * subtrahend)}, and whose scale is {@code max(this.getScale(),
+	 * subtrahend.getScale())}.
+	 * 
+	 * @param subtrahend
+	 *            value to be subtracted from this {@code MonetaryAmount}.
+	 * @return {@code this - subtrahend}
+	 */
+	public MonetaryAmount subtract(MonetaryAmount subtrahend);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this -
+	 * subtrahend)}, and whose scale is {@code max(this.getScale(),
+	 * subtrahend.getScale())}.
+	 * 
+	 * @param subtrahend
+	 *            value to be subtracted from this {@code MonetaryAmount}.
+	 * @return {@code this - subtrahend}
+	 */
+	public MonetaryAmount subtract(Number subtrahend);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is
+	 * <tt>(this<sup>n</sup>)</tt>, The power is computed exactly, to unlimited
+	 * precision.
+	 * 
+	 * <p>
+	 * The parameter {@code n} must be in the range 0 through 999999999,
+	 * inclusive. {@code ZERO.pow(0)} returns {@code 1}.
+	 * 
+	 * Note that future releases may expand the allowable exponent range of this
+	 * method.
+	 * 
+	 * @param n
+	 *            power to raise this {@code MonetaryAmount} to.
+	 * @return <tt>this<sup>n</sup></tt>
+	 * @throws ArithmeticException
+	 *             if {@code n} is out of range.
+	 * @since 1.0
+	 */
+	public MonetaryAmount pow(int n);
+
+	/**
+	 * Returns the size of an ulp, a unit in the last place, of this
+	 * {@code MonetaryAmount}. An ulp of a nonzero {@code MonetaryAmount} value
+	 * is the positive distance between this value and the
+	 * {@code MonetaryAmount} value next larger in magnitude with the same
+	 * number of digits. An ulp of a zero value is numerically equal to 1 with
+	 * the scale of {@code this}. The result is stored with the same scale as
+	 * {@code this} so the result for zero and nonzero values is equal to
+	 * {@code [1, this.getgetScale()]}.
+	 * 
+	 * @return the size of an ulp of {@code this}
+	 */
+	public MonetaryAmount ulp();
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this % divisor)}.
+	 * 
+	 * <p>
+	 * The remainder is given by
+	 * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}
+	 * . Note that this is not the modulo operation (the result can be
+	 * negative).
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @return {@code this % divisor}.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 */
+	public MonetaryAmount remainder(MonetaryAmount divisor);
+
+	/**
+	 * Returns a {@code MonetaryAmount} whose value is {@code (this % divisor)}.
+	 * 
+	 * <p>
+	 * The remainder is given by
+	 * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}
+	 * . Note that this is not the modulo operation (the result can be
+	 * negative).
+	 * 
+	 * @param divisor
+	 *            value by which this {@code MonetaryAmount} is to be divided.
+	 * @return {@code this % divisor}.
+	 * @throws ArithmeticException
+	 *             if {@code divisor==0}
+	 */
+	public MonetaryAmount remainder(Number divisor);
+
+	/**
+	 * Returns a Amount whose numerical value is equal to ({@code this} *
+	 * 10<sup>n</sup>). The scale of the result is {@code (this.getScale() - n)}
+	 * .
+	 * 
+	 * @throws ArithmeticException
+	 *             if the scale would be outside the range supported.
+	 */
+	public MonetaryAmount scaleByPowerOfTen(int n);
+
+	/**
+	 * Checks if the amount is zero.
+	 * 
+	 * @return true if the amount is zero
+	 */
+	public boolean isZero();
+
+	/**
+	 * Checks if the amount is greater than zero.
+	 * 
+	 * @return true if the amount is greater than zero
+	 */
+	public boolean isPositive();
+
+	/**
+	 * Checks if the amount is zero or greater.
+	 * 
+	 * @return true if the amount is zero or greater
+	 */
+	public boolean isPositiveOrZero();
+
+	/**
+	 * Checks if the amount is less than zero.
+	 * 
+	 * @return true if the amount is less than zero
+	 */
+	public boolean isNegative();
+
+	/**
+	 * Checks if the amount is zero or less.
+	 * 
+	 * @return true if the amount is zero or less
+	 */
+	public boolean isNegativeOrZero();
+
+	// -----------------------------------------------------------------------
+	/**
+	 * Returns a copy of this monetary value with the specified amount.
+	 * <p>
+	 * The returned instance will have a currency as returned by
+	 * {@link #getCurrency()} and the new amount. No rounding is performed on
+	 * the amount to be added.
+	 * <p>
+	 * This instance is immutable and unaffected by this method.
+	 * 
+	 * @param amount
+	 *            the amount to set in the returned instance, not null
+	 * @return the new instance with the input amount set, never null
+	 * @throws ArithmeticException
+	 *             if the scale of the amount is too large
+	 */
+	public MonetaryAmount from(Number amount);
+
+	/**
+	 * Returns a copy of this monetary value with the specified amount.
+	 * <p>
+	 * The returned instance will have a currency as returned by
+	 * {@link #getCurrency()} and the new amount. No rounding is performed on
+	 * the amount to be added.
+	 * <p>
+	 * This instance is immutable and unaffected by this method.
+	 * 
+	 * @param currency
+	 *            the target currency
+	 * @param amount
+	 *            the amount to set in the returned instance, not null
+	 * @return the new instance with the input amount and currency set, never
+	 *         null
+	 * @throws ArithmeticException
+	 *             if the scale of the amount is too large
+	 */
+	public MonetaryAmount from(CurrencyUnit currency, Number amount);
+
+	/**
+	 * Applies the given {@link MonetaryOperator} to this {@link MonetaryAmount}.
+	 * 
+	 * @param operator
+	 *            the operator, not null.
+	 * @return the result of the operation, never null.
+	 */
+	public MonetaryAmount with(MonetaryOperator operator);
+
+	// -------------------- Introspection and value methods, similar to
+	// java.lang.Number; java.lang.BigDecimal
+
+	/**
+	 * * Gets the scale of the amount.
+	 * <p>
+	 * The scale has the same meaning as in {@link java.math.BigDecimal}.
+	 * Positive values represent the number of decimal places in use. For
+	 * example, a scale of 2 means that the money will have two decimal places
+	 * such as 'USD 43.25'.
+	 * <p>
+	 * For {@code MonetaryAmount}, the scale is fixed and always matches that of
+	 * the currency.
+	 * 
+	 * @return the scale in use, typically 2 but could be 0, 1 and 3
+	 */
+	public int getScale();
+
+	/**
+	 * Returns the <i>internal precision</i> of this {@code MonetaryAmount}. The
+	 * precision is the number of digits in the unscaled value.
+	 * 
+	 * <p>
+	 * The precision of a zero value is 1.
+	 * 
+	 * @return the precision of this {@code MonetaryAmount}.
+	 */
+	public int getPrecision();
+
+	/**
+	 * Returns the value of the specified number as an <code>int</code>. This
+	 * may involve rounding or truncation.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>int</code>.
+	 */
+	public int intValue();
+
+	/**
+	 * Converts this {@code MonetaryAmount} to an {@code int}, checking for lost
+	 * information. If this {@code MonetaryAmount} has a nonzero fractional part
+	 * or is out of the possible range for an {@code int} result then an
+	 * {@code ArithmeticException} is thrown.
+	 * 
+	 * @return this {@code MonetaryAmount} converted to an {@code int}.
+	 * @throws ArithmeticException
+	 *             if {@code this} has a nonzero fractional part, or will not
+	 *             fit in an {@code int}.
+	 */
+	public int intValueExact();
+
+	/**
+	 * Returns the value of the specified number as a <code>long</code>. This
+	 * may involve rounding or truncation.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>long</code>.
+	 */
+	public long longValue();
+
+	/**
+	 * Converts this {@code MonetaryAmount} to a {@code long}, checking for lost
+	 * information. If this {@code MonetaryAmount} has a nonzero fractional part
+	 * or is out of the possible range for a {@code long} result then an
+	 * {@code ArithmeticException} is thrown.
+	 * 
+	 * @return this {@code MonetaryAmount} converted to a {@code long}.
+	 * @throws ArithmeticException
+	 *             if {@code this} has a nonzero fractional part, or will not
+	 *             fit in a {@code long}.
+	 */
+	public long longValueExact();
+
+	/**
+	 * Returns the value of the specified number as a <code>float</code>. This
+	 * may involve rounding.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>float</code>.
+	 */
+	public float floatValue();
+
+	/**
+	 * Returns the value of the specified number as a <code>double</code>. This
+	 * may involve rounding.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>double</code>.
+	 */
+	public double doubleValue();
+
+	/**
+	 * Returns the value of the specified number as a <code>byte</code>. This
+	 * may involve rounding or truncation.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>byte</code>.
+	 */
+	public byte byteValue();
+
+	/**
+	 * Returns the value of the specified number as a <code>short</code>. This
+	 * may involve rounding or truncation.
+	 * 
+	 * @return the numeric value represented by this object after conversion to
+	 *         type <code>short</code>.
+	 */
+	public short shortValue();
+
+	/**
+	 * Converts this {@code MonetaryAmount} to a {@code short}, checking for
+	 * lost information. If this {@code MonetaryAmount} has a nonzero fractional
+	 * part or is out of the possible range for a {@code short} result then an
+	 * {@code ArithmeticException} is thrown.
+	 * 
+	 * @return this {@code MonetaryAmount} converted to a {@code short}.
+	 * @throws ArithmeticException
+	 *             if {@code this} has a nonzero fractional part, or will not
+	 *             fit in a {@code short} .
+	 */
+	public short shortValueExact();
+
+	/**
+	 * Returns the signum function of this {@code MonetaryAmount}.
+	 * 
+	 * @return -1, 0, or 1 as the value of this {@code MonetaryAmount} is
+	 *         negative, zero, or positive.
+	 */
+	public int signum();
+
+	/**
+	 * Checks if this amount is less compared to the amount passed.
+	 * 
+	 * @param amount
+	 *            The amount to compare to.
+	 * @return {@code true}, if this amount is less compared to the amount
+	 *         passed.
+	 */
+	public boolean isLessThan(MonetaryAmount amount);
+
+	/**
+	 * Checks if this amount is less or the same compared to the amount passed.
+	 * 
+	 * @param amount
+	 *            The amount to compare to.
+	 * @return {@code true}, if this amount is less or the same compared to the
+	 *         amount passed.
+	 */
+	public boolean isLessThanOrEqualTo(MonetaryAmount amount);
+
+	/**
+	 * Checks if this amount is greater compared to the amount passed.
+	 * 
+	 * @param amount
+	 *            The amount to compare to.
+	 * @return {@code true}, if this amount is greater compared to the amount
+	 *         passed.
+	 */
+	public boolean isGreaterThan(MonetaryAmount amount);
+
+	/**
+	 * Checks if this amount is greater or the same compared to the amount
+	 * passed.
+	 * 
+	 * @param amount
+	 *            The amount to compare to.
+	 * @return {@code true}, if this amount is greater or the same compared to
+	 *         the amount passed.
+	 */
+	public boolean isGreaterThanOrEqualTo(MonetaryAmount amount);
+
+	/**
+	 * Checks if this amount is the same compared to the amount passed. This is
+	 * a convenience method to reflect {@link #same(Number)} also for amounts,
+	 * but basically should behave similarly as {@link #equals(Object)}.
+	 * 
+	 * @param number
+	 *            The number to compare to.
+	 * @return {@code true}, if this amount's value is the same compared to the
+	 *         number passed.
+	 */
+	public boolean isEqualTo(MonetaryAmount amount);
+
+	/**
+	 * Checks if this amount is not the same compared to the amount passed.
+	 * 
+	 * @param amount
+	 *            The amount to compare to.
+	 * @return {@code true}, if this amount's value is not the same compared to
+	 *         the number passed, or the {@link CurrencyUnit} of the amount
+	 *         passed does not match this instances {@link CurrencyUnit}.
+	 * @see #hasSameCurrencyAs(MonetaryAmount)
+	 */
+	public boolean isNotEqualTo(MonetaryAmount amount);
+
+	// -------------------------------------------- Misc
+
+	/**
+	 * Gets the monetary amount using the passed target type. This method
+	 * allows to support different return types, depending of the concrete
+	 * implementation. E.g. {@link BigDecimal}, {@link java.lang.Number} and the
+	 * numeric wrapper types should be supported within SE environments, whereas
+	 * on other environments, it may be different.
+	 * <p>
+	 * This returns the monetary value as a {@code T}. No scaling will be
+	 * affected.
+	 * 
+	 * @return the amount represented as T, never {@code null}
+	 * @throws IllegalArgumentException
+	 *             if the representation type is not supported, or the target
+	 *             type can not provide the precision required.
+	 */
+	public <T> T asType(Class<T> type);
+
+	/**
+	 * Access the class that models the representation of the numeric part of
+	 * the amount. The internal value can be accessed by calling
+	 * {@link #asType(Class)} passing the result of this method.
+	 * 
+	 * @return The class that represents the numeric representation, never null.
+	 * @see #asType(Class)
+	 */
+	public Class<?> getNumberType();
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryFunction.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryFunction.java
new file mode 100644
index 0000000..4e45bdd
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryFunction.java
@@ -0,0 +1,28 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+/**
+ * This interface defines a {@link MonetaryFunction}. It is considered to be
+ * adapted/compatible with {@code java.util.function.Function} as introduced in
+ * Java 8.
+ * 
+ * @author Werner Keil
+ * @version 0.9.1
+ * @param <T>
+ *            The input type of the function.
+ * @param <R>
+ *            The result type of the function.
+ * @deprecated this is a stub, replacing it by JSR 354 as soon as it's in MavenCentral!
+ */
+public interface MonetaryFunction<T, R> {
+
+	/**
+	 * Apply a function to the input argument T, yielding an appropriate result R.
+	 * @param value the input value
+	 * @return the result of the function
+	 */
+	public R apply(T value);
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryOperator.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryOperator.java
new file mode 100644
index 0000000..be71bd3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/internal/MonetaryOperator.java
@@ -0,0 +1,28 @@
+/*
+ * Backport, stub for JavaMoney 
+ */
+package org.eclipse.uomo.business.internal;
+
+/**
+ * This interface defines a {@link MonetaryOperator}. It is hereby important to
+ * distinguish between <i>internal rounding</i> such as implied by the maximal
+ * precision/scale of an amount, and <i>rounding</i> applied to a
+ * {@link MonetaryAmount} or a calculation algorithm. Since different use cases
+ * may require <i>rounding</i> done at very different stages and differently
+ * within a complex financial calculation, {@link MonetaryOperator} is not
+ * directly attached to a monetary type, e.g. a {@link MonetaryAmount}.
+ * <p>
+ * Nevertheless the JSR's extensions provide a RoundingMonetaryAmount, which
+ * wraps a {@link MonetaryAmount} and adds implicit rounding.
+ * 
+ * <p>
+ * This interface is considered to be adapted/compatible with {@code java.util.function.UnaryOperator} 
+ * as introduced in Java 8.
+ * 
+ * @version 0.9.1
+ * @author Werner Keil
+ * @deprecated this is a stub, replacing it by JSR 354 as soon as it's in MavenCentral!
+ */
+public interface MonetaryOperator extends MonetaryFunction<MonetaryAmount,MonetaryAmount> {
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MonetaryUnits.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MonetaryUnits.java
new file mode 100644
index 0000000..b89e3f0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MonetaryUnits.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2006, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import org.eclipse.uomo.business.types.IMoney;
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.util.Currency;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.6, $Date: 2013-05-20 $
+ */
+public final class MonetaryUnits extends AbstractSystemOfUnits {
+	/**
+	 * The predefined name space for ISO 4217 currencies, similar to
+	 * {@link Currency}.
+	 */
+	public static final String ISO_NAMESPACE = "ISO-4217";
+	
+	/**
+	 * The Australian Dollar currency unit.
+	 */
+	public static final MoneyUnit<IMoney> AUD = monetary(new MoneyUnit<IMoney>("AUD")); //$NON-NLS-1$
+	
+	// Use currency not defined as constant (Rupees).
+	public static final Unit<IMoney> INR = monetary(new MoneyUnit<IMoney>("INR")); //$NON-NLS-1$
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private MonetaryUnits() {
+    }
+	
+    /**
+     * Returns the unique instance of this class.
+     *
+     * @return the MonetaryUnits instance.
+     */
+    public static SystemOfUnits getInstance() {
+        return INSTANCE;
+    }
+    private static final MonetaryUnits INSTANCE = new MonetaryUnits();
+	
+	/**
+     * Adds a new unit to the collection.
+     *
+     * @param  unit the unit being added.
+     * @return <code>unit</code>.
+     */
+    private final static <U extends Unit<?>> U monetary(U unit) {
+        UNITS.add(unit);
+        return unit;
+    }
+
+	public String getName() {
+		return getClass().getSimpleName();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyAmount.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyAmount.java
new file mode 100644
index 0000000..87b94c5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyAmount.java
@@ -0,0 +1,715 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+
+import org.eclipse.uomo.business.internal.CurrencyUnit;
+import org.eclipse.uomo.business.internal.MonetaryAmount;
+import org.eclipse.uomo.business.internal.MonetaryOperator;
+import org.eclipse.uomo.business.types.IMoney;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.QuantityAmount;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.math.BigDecimal;
+import com.ibm.icu.util.Currency;
+
+/**
+ * This class represents an amount of money specified in a given
+ * {@link Currency} (convenience method).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.5, $Date: 2013-05-11 $
+ */
+public class MoneyAmount extends QuantityAmount<IMoney> implements IMoney, MonetaryAmount,
+		Comparable<MonetaryAmount> {
+
+	/**
+	 * Holds the base unit for money quantities (symbol "$").
+	 */
+	public final static MoneyUnit<IMoney> UNIT = new MoneyUnit<IMoney>(
+			"$");
+
+	/**
+	 * Creates a money amount always on the heap independently from the current
+	 * {@link javolution.context.AllocatorContext allocator context}. To allow
+	 * for custom object allocation policies, static factory methods
+	 * <code>valueOf(...)</code> are recommended.
+	 * 
+	 * @param value
+	 *            the value stated in the specified currency.
+	 * @param currency
+	 *            the currency in which the value is stated.
+	 */
+	public MoneyAmount(Number value, MoneyUnit unit) {
+		super(value, unit);
+	}
+
+	/**
+	 * Returns the money amount corresponding to the specified Number value
+	 * and currency.
+	 * 
+	 * @param value
+	 *            the value stated in the specified currency.
+	 * @param currency
+	 *            the currency in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+	public static MoneyAmount of(Number value, CurrencyUnit currency) {
+		return new MoneyAmount(value, (MoneyUnit)currency);
+	}
+	
+	/**
+	 * Returns the money amount corresponding to the specified Number value
+	 * and currency.
+	 * 
+	 * @param value
+	 *            the value stated in the specified currency.
+	 * @param currency
+	 *            the currency in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+//	static MoneyAmount of(Number value, java.util.Currency currency) {
+//		MoneyAmount amount = new MoneyAmount(value, currency);
+//		return amount;
+//	}
+
+	/**
+	 * Returns the money amount corresponding to the specified Number value
+	 * and currency.
+	 * 
+	 * @param value
+	 *            the value stated in the specified currency.
+	 * @param currency
+	 *            the currency in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+	public static MoneyAmount of(Number value, Unit<?> currency) {
+		return new MoneyAmount(value, (MoneyUnit) currency);
+	}
+
+	/**
+	 * Returns the money amount corresponding to the specified value and cents.
+	 * 
+	 * @param value
+	 *            the integer value in the specified currency.
+	 * @param cents
+	 *            the cents value in the specified currency.
+	 * @param currency
+	 *            the currency in which the value and cents are stated.
+	 * @return the corresponding amount.
+	 */
+	public static MoneyAmount of(long value, int cents, Currency currency) {
+		return new MoneyAmount(BigDecimal.valueOf(value * 100
+				+ cents, -2), (MoneyUnit) currency);
+	}
+
+	/**
+	 * Returns the money amount corresponding to the specified generic amount.
+	 * 
+	 * @param amount
+	 *            the raw amount.
+	 * @return the corresponding money amount stated in an existing
+	 *         {@link Currency}.
+	 * @throws ClassCastException
+	 *             if the SI unit of the specified amount is not a
+	 *             {@link Currency}.
+	 */
+	public static MoneyAmount of(QuantityAmount<IMoney> amount) {
+		// MoneyAmount amountSI = amount.toSI();
+		return MoneyAmount.of(BigDecimal.valueOf(amount.getNumber()
+				.doubleValue()), amount.unit().getSystemUnit());
+	}
+
+	
+	/**
+	 * Returns the money amount corresponding to the specified Number value
+	 * and currency code.
+	 * 
+	 * @param value
+	 *            the value stated in the specified currency.
+	 * @param currency
+	 *            the currency in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+	public static MoneyAmount of(String code, Number value) {
+		return new MoneyAmount(value, MoneyUnit.of(code));
+	}
+	
+	/**
+	 * Overrides the default {@link #toString()} to show only the currency
+	 * {@link Currency#getFractionDigits() fraction digits} of the associated
+	 * currency (e.g. rounding to closest cents).
+	 * 
+	 * @return the string representation of this money amount.
+	 */
+	public String toStringLocale() {
+		BigDecimal value = (BigDecimal) this.getNumber();
+		// int digits = ((Currency) this.getUnit()).getDefaultFractionDigits();
+		// int exponent = value.getExponent();
+		// LargeInteger significand = value.getSignificand();
+		// int scale = exponent + digits;
+		// significand = significand.E(scale);
+		// exponent -= scale;
+		// value = BigDecimal.valueOf(significand, exponent);
+		NumberFormat numberFormat = NumberFormat.getInstance();
+		StringBuffer tmp = new StringBuffer();
+		numberFormat.format(value, tmp, new FieldPosition(0));
+		tmp.append(' ');
+		tmp.append(this.unit().toString());
+		return tmp.toString();
+	}
+
+	// public MoneyAmount opposite() {
+	// return MoneyAmount.valueOf(_value.opposite(), getCurrency());
+	// }
+
+	protected MoneyAmount plus(IMoney that) {
+		// Measure<BigDecimal, ?> amount = that.to((Unit) getCurrency());
+		return MoneyAmount.of(this.getNumber().doubleValue()
+				+ that.value().doubleValue(), getCurrency());
+	}
+	
+	protected MoneyAmount plus(MoneyAmount that) {
+		// Measure<BigDecimal, ?> amount = that.to((Unit) getCurrency());
+		return MoneyAmount.of(this.getNumber().doubleValue()
+				+ that.getNumber().doubleValue(), getCurrency());
+	}
+
+	protected MoneyAmount minus(MoneyAmount that) {
+		// MoneyAmount amount = that.to((Unit) getCurrency());
+		return MoneyAmount.of(this.getNumber().doubleValue()
+				- that.getNumber().doubleValue(), getCurrency());
+	}
+
+	public MoneyAmount multiply(Number that) {
+		return MoneyAmount.of(
+				getNumber().doubleValue() * that.doubleValue(), getCurrency());
+	}
+
+	public MoneyAmount multiply(long n) {
+		return MoneyAmount.of(getNumber().longValue() * n,
+				getCurrency());
+	}
+
+	protected MoneyAmount multiply(MoneyAmount that) {
+		Unit<?> unit = unit().multiply(that.unit());
+		return MoneyAmount.of(((BigDecimal) getNumber())
+				.multiply((BigDecimal) that.getNumber()), unit);
+	}
+
+	public MoneyAmount pow(int exp) {
+		return MoneyAmount.of(((BigDecimal) getNumber()).pow(BigDecimal
+				.valueOf(exp)), unit().pow(exp));
+	}
+
+	// protected MoneyAmount inverse() {
+	// return MoneyAmount.valueOf(((BigDecimal) getNumber()).inverse(),
+	// unit().inverse());
+	// }
+
+	public MoneyAmount divide(long n) {
+		return MoneyAmount.of(getNumber().longValue() / n,
+				getCurrency());
+	}
+
+	protected MoneyAmount divide(MoneyAmount that) {
+		Unit<?> unit = unit().divide(that.unit());
+		return MoneyAmount.of(((BigDecimal) getNumber())
+				.divide((BigDecimal) that.getNumber()), unit);
+	}
+
+	public MoneyAmount copy() {
+		return MoneyAmount.of(getNumber(), getCurrency());
+	}
+
+	/**
+	 * Get the unit (convenience to avoid cast).
+	 * 
+	 * @draft UOMo 0.5
+	 * @provisional This API might change or be removed in a future release.
+	 */
+	@SuppressWarnings("unchecked")
+	public MoneyUnit<IMoney> unit() {
+		return (MoneyUnit<IMoney>) getUnit();
+	}
+
+	public int compareTo(IMoney o) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	public double doubleValue(Unit<IMoney> unit) {
+		Unit<IMoney> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterToAny(myUnit);
+			return converter.convert(getNumber().doubleValue());
+		} catch (UnconvertibleException e) {
+			throw e;
+		} catch (IncommensurableException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	public long longValue(Unit<IMoney> unit) throws ArithmeticException {
+		Unit<IMoney> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterToAny(myUnit);
+			return (converter.convert(BigDecimal.valueOf(super.getNumber()
+					.longValue())).longValue());
+		} catch (UnconvertibleException e) {
+			throw e;
+		} catch (IncommensurableException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	public IMeasure<IMoney> substract(IMeasure<IMoney> that) {
+		return minus((MoneyAmount) that);
+	}
+
+	public IMeasure<IMoney> divide(IMeasure<?> that) {
+		return divide((MoneyAmount) that);
+	}
+
+	public IMeasure<IMoney> multiply(IMeasure<?> that) {
+		return multiply((MoneyAmount) that);
+	}
+
+	public IMeasure<IMoney> to(Unit<IMoney> unit) {
+		return to(unit, MathContext.DECIMAL32);
+	}
+
+	protected IMeasure<IMoney> to(Unit<IMoney> unit, MathContext ctx) {
+		if (this.unit().equals(unit))
+			return this;
+		UnitConverter cvtr = this.unit().getConverterTo(unit);
+		if (cvtr == AbstractConverter.IDENTITY)
+			return (IMeasure<IMoney>) of(this.getNumber(), unit);
+		return (IMeasure<IMoney>) of(convert(this.getNumber(), cvtr, ctx),
+				unit);
+	}
+
+	// Try to convert the specified value.
+	private static Number convert(Number value, UnitConverter cvtr,
+			MathContext ctx) {
+		if (cvtr instanceof RationalConverter) { // Try converting through Field
+													// methods.
+			RationalConverter rCvtr = (RationalConverter) cvtr;
+			BigInteger dividend = rCvtr.getDividend();
+			BigInteger divisor = rCvtr.getDivisor();
+			if (dividend.abs().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+				throw new ArithmeticException("Multiplier overflow");
+			if (divisor.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+				throw new ArithmeticException("Divisor overflow");
+			return (value.longValue() * dividend.longValue())
+					/ (divisor.longValue());
+		} else if (cvtr instanceof AbstractConverter.Compound
+				&& cvtr.isLinear()) { // Do it in two parts.
+			AbstractConverter.Compound compound = (AbstractConverter.Compound) cvtr;
+			Number firstConversion = convert(value, compound.getRight(), ctx);
+			Number secondConversion = convert(firstConversion,
+					compound.getLeft(), ctx);
+			return secondConversion;
+		} else { // Try using BigDecimal as intermediate.
+			BigDecimal decimalValue = BigDecimal.valueOf(value.doubleValue());
+			Number newValue = cvtr.convert(decimalValue.toBigDecimal(), ctx);
+			return newValue;
+			// if (((FieldNumber)value) instanceof Decimal)
+			// return (N)((FieldNumber)Decimal.valueOf(newValue));
+			// if (((FieldNumber)value) instanceof Float64)
+			// return (N)((FieldNumber)Float64.valueOf(newValue.doubleValue()));
+			// throw new ArithmeticException(
+			// "Generic amount conversion not implemented for amount of type " +
+			// value.getClass());
+		}
+	}
+	
+	private final BigDecimal bigNumber() {
+		if (getNumber() instanceof BigDecimal) {
+			return (BigDecimal)getNumber();
+		} else {
+			throw new UOMoRuntimeException(
+					new IllegalArgumentException("Cannot represent as BigDecimal"));
+		}
+	}
+
+	/**
+	 * Generate a 'preference neutral' string from Money value.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+		return null;
+	}
+
+	public Number value() {
+		return getNumber();
+	}
+
+	public IMeasure<? extends IMeasure<IMoney>> inverse() {
+		final IMeasure<? extends IMeasure<IMoney>> m = of(value(), unit()
+				.inverse());
+		return m;
+	}
+
+	public int compareTo(MonetaryAmount o) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	 
+	public MonetaryAmount abs() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public MonetaryAmount add(Number augend) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount divide(MonetaryAmount divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount divide(Number divisor) {
+		// TODO Auto-generated method stub
+		//return of((BigDecimal)value()).divide((BigDecimal)divisor));
+		return null;
+	}
+
+	 
+	public MonetaryAmount[] divideAndRemainder(MonetaryAmount divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount[] divideAndRemainder(Number divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount divideToIntegralValue(MonetaryAmount divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount divideToIntegralValue(Number divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount negate() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount plus() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount subtract(MonetaryAmount subtrahend) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount subtract(Number subtrahend) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount ulp() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount remainder(MonetaryAmount divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount remainder(Number divisor) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount scaleByPowerOfTen(int n) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public boolean isZero() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isPositive() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isPositiveOrZero() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isNegative() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isNegativeOrZero() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public MonetaryAmount from(Number amount) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public MonetaryAmount from(CurrencyUnit currency, Number amount) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	 
+	public MonetaryAmount with(MonetaryOperator operator) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#getScale()
+	 */
+	public int getScale() {
+		return this.bigNumber().scale();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#getPrecision()
+	 */
+	public int getPrecision() {
+		//return bigNumber().precision(); // FIXME in ICU4J 50+
+		return -1;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#intValue()
+	 */
+	public int intValue() {
+		return this.getNumber().intValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#intValueExact()
+	 */
+	public int intValueExact() {
+		return bigNumber().intValueExact();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#longValue()
+	 */
+	public long longValue() {
+		return this.getNumber().longValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#longValueExact()
+	 */
+	public long longValueExact() {
+		return bigNumber().longValueExact();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#floatValue()
+	 */
+	public float floatValue() {
+		return this.getNumber().floatValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#doubleValue()
+	 */
+	public double doubleValue() {
+		return this.getNumber().doubleValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#byteValue()
+	 */
+	public byte byteValue() {
+		return this.getNumber().byteValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#shortValue()
+	 */
+	public short shortValue() {
+		return getNumber().shortValue();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#shortValueExact()
+	 */
+	public short shortValueExact() {
+		return bigNumber().shortValueExact();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#signum()
+	 */
+
+	public int signum() {
+		return bigNumber().signum();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#toEngineeringString()
+	 */
+	public String toEngineeringString() {
+		return getCurrency().getCurrencyCode() + ' '
+				//+ bigNumber().toEngineeringString(); // FIXME in ICU4J 50+
+				+ bigNumber().toString();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see MonetaryAmount#toPlainString()
+	 */
+	public String toPlainString() {
+		return getCurrency().getCurrencyCode() + ' '
+				//+ bigNumber().toPlainString();  // FIXME in ICU4J 50+
+				+ bigNumber().toString();
+	}
+	 
+	public boolean isLessThan(MonetaryAmount amount) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isLessThanOrEqualTo(MonetaryAmount amount) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isGreaterThan(MonetaryAmount amount) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isGreaterThanOrEqualTo(MonetaryAmount amount) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isEqualTo(MonetaryAmount amount) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	 
+	public boolean isNotEqualTo(MonetaryAmount amount) {
+		return !getNumber().equals(amount);
+	}
+
+	public <T> T asType(Class<T> type) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Class<?> getNumberType() {
+		return getNumber().getClass();
+	}
+
+	public MoneyAmount multiply(MonetaryAmount multiplicand) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	 
+	public CurrencyUnit getCurrency() {
+		return (CurrencyUnit)unit();
+	}
+
+	@Override
+	public IMoney add(IMeasure<IMoney> that) {
+		return plus((IMoney) that);
+	}
+
+	@Override
+	public MonetaryAmount add(MonetaryAmount augend) {
+		return plus((MoneyAmount) augend);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyConverter.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyConverter.java
new file mode 100644
index 0000000..4cff455
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyConverter.java
@@ -0,0 +1,267 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import static java.util.FormattableFlags.LEFT_JUSTIFY;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.Formattable;
+import java.util.Formatter;
+import java.util.List;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.uomo.business.internal.ExchangeRate;
+import org.eclipse.uomo.business.internal.Messages;
+import org.eclipse.uomo.business.types.IMoney;
+import org.eclipse.uomo.units.AbstractConverter;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * <p>
+ * This class represents a converter between two currencies.
+ * </p>
+ * 
+ * <p>
+ * Currency converters convert values based upon the current exchange rate
+ * {@link Currency#getExchangeRate() exchange rate}. If the
+ * {@link Currency#getExchangeRate() exchange rate} from the target currency to
+ * the source currency is not set, conversion fails. In others words, the
+ * converter from a currency <code>A</code> to a currency <code>B</code> is
+ * independant from the converter from <code>B</code> to <code>A</code>.
+ * </p>
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 5.2.3 ($Revision: 214 $), $Date: 2010-09-13 23:54:08 +0200 (Mo, 13 Sep 2010) $
+ * @deprecated use JSR 354
+ */
+public class MoneyConverter extends AbstractConverter implements Formattable {
+
+	/**
+     * 
+     */
+	private static final long serialVersionUID = -3943843029548497620L;
+
+	/**
+	 * Holds the exchange rate.
+	 */
+	private final ExchangeRate rate;
+
+	private void checkFactor(Number factor) {
+		if (factor == null)
+			throw new UnsupportedOperationException(NLS.bind(
+					Messages.CurrencyConverter_exchangeRate_not_set,
+					rate.getSource(), rate.getTarget())); //$NON-NLS-1$
+	}
+
+	private Currency fromJDK(java.util.Currency currency) {
+		return Currency.getInstance(currency.getCurrencyCode());
+	}
+
+	/**
+	 * Creates the currency converter from the source currency to the target
+	 * currency.
+	 * 
+	 * @param source
+	 *            the source currency.
+	 * @param target
+	 *            the target currency.
+	 * @param factor
+	 *            the multiplier factor from source to target.
+	 * @return the corresponding converter.
+	 */
+	private MoneyConverter(Currency source, Currency target, Number factor) {
+		rate = new MoneyExchangeRate(source, target, factor);
+	}
+
+	/**
+	 * Creates the currency converter from the source currency to the target
+	 * currency.
+	 * 
+	 * @param source
+	 *            the source currency.
+	 * @param target
+	 *            the target currency.
+	 * @param factor
+	 *            the multiplier factor from source to target.
+	 * @return the corresponding converter.
+	 */
+	@SuppressWarnings("unchecked")
+	public MoneyConverter(MoneyUnit<?> source, Unit<IMoney> target,
+			Number factor) {
+		if (target instanceof MoneyUnit<?>) {
+			rate = new MoneyExchangeRate(source, (MoneyUnit<IMoney>) target,
+					factor);
+		} else {
+			Currency defCurrency = Currency.getInstance(ULocale.getDefault());
+			rate = new MoneyExchangeRate(defCurrency, defCurrency, factor);
+		}
+	}
+
+	/**
+	 * Creates the currency converter from the source currency to the target
+	 * currency using <strong>JDK</strong> types.
+	 * 
+	 * @param source
+	 *            the source currency (<strong>JDK</strong>).
+	 * @param target
+	 *            the target currency (<strong>JDK</strong>).
+	 * @param factor
+	 *            the multiplier factor from source to target.
+	 * @return the corresponding converter.
+	 */
+	public MoneyConverter(java.util.Currency source,
+			java.util.Currency target, Number factor) {
+		rate = new MoneyExchangeRate(fromJDK(source), fromJDK(target), factor);
+	}
+
+	/**
+	 * Returns the source currency.
+	 * 
+	 * @return the source currency.
+	 */
+	public Currency getSource() {
+		return rate.getSource();
+	}
+
+	/**
+	 * Returns the target currency.
+	 * 
+	 * @return the target currency.
+	 */
+	public Currency getTarget() {
+		return rate.getTarget();
+	}
+
+	public MoneyConverter inverse() {
+		return new MoneyConverter(rate.getTarget(), rate.getSource(),
+				rate.getFactor());
+	}
+
+	public MoneyConverter negate() {
+		return new MoneyConverter(rate.getSource(), rate.getTarget(), -rate
+				.getFactor().doubleValue());
+	}
+
+	public double convert(double value) {
+		// Number factor = getExchangeRate(rate.getTarget());
+		Number factor = rate.getFactor();
+		checkFactor(factor);
+		return factor.doubleValue() * value;
+	}
+
+	public BigDecimal convert(BigDecimal value, MathContext ctx)
+			throws ArithmeticException {
+		// Number factor = rate.getSource().getExchangeRate(rate.getTarget());
+		Number factor = rate.getFactor();
+		checkFactor(factor);
+		if (factor instanceof BigDecimal)
+			return value.multiply((BigDecimal) factor, ctx);
+		if (factor instanceof Number) {
+			return value.multiply(
+					(BigDecimal.valueOf(((Number) factor).doubleValue())), ctx);
+		} else { // Reverts to double convert.
+			return value
+					.multiply(BigDecimal.valueOf(factor.doubleValue()), ctx);
+		}
+	}
+
+	public Number convert(Number value) {
+		if (value instanceof BigDecimal) {
+			return convert((BigDecimal) value, MathContext.DECIMAL128);
+		} else {
+			return convert(value.doubleValue());
+		}
+	}
+
+	@Override
+	public boolean equals(Object cvtr) {
+		if (!(cvtr instanceof MoneyConverter))
+			return false;
+		MoneyConverter that = (MoneyConverter) cvtr;
+		return this.rate.getSource().equals(that.rate.getSource())
+				&& this.rate.getTarget().equals(that.rate.getTarget());
+	}
+
+	@Override
+	public int hashCode() {
+		return rate.getSource().hashCode() + rate.getTarget().hashCode();
+	}
+
+	@Override
+	public final String toString() {
+		if (getSource().equals(getTarget())) {
+			return getSource().getSymbol();
+		}
+		return String.format(Messages.CurrencyConverter_toString, getSource()
+				.getSymbol(), getTarget().getSymbol());
+	}
+
+	public boolean isLinear() {
+		return true;
+	}
+
+	public UnitConverter concatenate(UnitConverter converter) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public List<UnitConverter> getCompoundConverters() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public boolean isIdentity() {
+		return false;
+	}
+
+	public ExchangeRate getExchangeRate() {
+		return rate;
+	}
+
+	public void formatTo(Formatter fmt, int f, int width, int precision) {
+		StringBuilder sb = new StringBuilder();
+
+		// decide form of name
+		String name = getSource().toString();
+		String symbol = getSource().getSymbol();
+		// if (fmt.locale().equals(Locale.FRANCE))
+		// name = frenchCompanyName;
+		// boolean alternate = (f & ALTERNATE) == ALTERNATE;
+		boolean usesymbol = true; // alternate || (precision != -1 && precision
+									// < 10);
+		String out = (usesymbol ? symbol : name);
+
+		// apply precision
+		if (precision == -1 || out.length() < precision) {
+			// write it all
+			sb.append(out);
+		} else {
+			sb.append(out.substring(0, precision - 1)).append('*');
+		}
+
+		// apply width and justification
+		int len = sb.length();
+		if (len < width)
+			for (int i = 0; i < width - len; i++)
+				if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY)
+					sb.append(' ');
+				else
+					sb.insert(0, ' ');
+
+		fmt.format(sb.toString());
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyCurrency.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyCurrency.java
new file mode 100644
index 0000000..07264e5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyCurrency.java
@@ -0,0 +1,712 @@
+/**
+ * Copyright (c) 2006, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import static org.eclipse.uomo.business.money.MonetaryUnits.ISO_NAMESPACE;
+
+import java.io.Serializable;
+//import java.util.Currency;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.eclipse.uomo.business.internal.CurrencyUnit;
+import org.eclipse.uomo.business.internal.Localizable;
+
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Adapter that implements the  {@link CurrencyUnit} interface using the
+ * ICU4J {@link com.ibm.icu.util.Currency}.
+ * 
+ * @version 0.2.2
+ * @author Werner Keil
+ * @deprecated merge into MoneyUnit
+ */
+public class MoneyCurrency extends com.ibm.icu.util.Currency implements CurrencyUnit, Localizable,
+		Comparable<CurrencyUnit> {
+
+	/**
+	 * serialVersionUID.
+	 */
+	private static final long serialVersionUID = -2523936311372374236L;
+
+	/** namespace for this currency. */
+	private final String namespace;
+	/** currency code for this currency. */
+	private final String currencyCode;
+	/** valid from, or {@code null}. */
+	private final Long validFrom;
+	/** valid until, or {@code null}. */
+	private final Long validUntil;
+	/** true, if legal tender. */
+	private final boolean legalTender;
+	/** true, if it is a virtual currency. */
+	private final boolean virtual;
+
+	private static final Map<String, MoneyCurrency> CACHED = new ConcurrentHashMap<String, MoneyCurrency>();
+
+	private static final Logger LOGGER = Logger.getLogger(MoneyCurrency.class
+			.getName());
+
+	/**
+	 * Private constructor.
+	 * 
+	 * @param currency
+	 */
+	private MoneyCurrency(String namespace, String code, int numCode,
+			int fractionDigits, Long validFrom, Long validUntil, boolean legal,
+			boolean virtual) {
+		super(code);
+		this.namespace = namespace;
+		this.currencyCode = code;
+		this.validFrom = validFrom;
+		this.validUntil = validUntil;
+		this.legalTender = legal;
+		this.virtual = virtual;
+	}
+
+	/**
+	 * Private constructor.
+	 * 
+	 * @param currency
+	 */
+	private MoneyCurrency(Currency currency) {
+		super(currency != null ? currency.getCurrencyCode() : "");
+		if (currency == null) {
+			throw new IllegalArgumentException("Currency required.");
+		}
+		this.namespace = ISO_NAMESPACE;
+		this.currencyCode = currency.getCurrencyCode();
+		currency.getDefaultFractionDigits();
+		this.validFrom = null;
+		this.validUntil = null; // TODO Adapt for hisotoric one, e.g. AFA
+		this.legalTender = !this.currencyCode.startsWith("X"); // TODO check for
+																// each code in
+																// util.Currency
+																// here;
+		this.virtual = this.currencyCode.equals("XXX"); // TODO check for each
+														// code in util.Currency
+														// here;
+	}
+
+	/**
+	 * Access a new instance based on {@link Currency}.
+	 * 
+	 * @param currency
+	 *            the currency unitm not null.
+	 * @return the new instance, never null.
+	 */
+	public static MoneyCurrency of(Currency currency) {
+		String key = ISO_NAMESPACE + ':' + currency.getCurrencyCode();
+		MoneyCurrency cachedItem = CACHED.get(key);
+		if (cachedItem == null) {
+			cachedItem = new JDKCurrencyAdapter(currency);
+			CACHED.put(key, cachedItem);
+		}
+		return cachedItem;
+	}
+
+	/**
+	 * Access a new instance based on {@link Currency}.
+	 * 
+	 * @param currency
+	 *            the currency unitm not null.
+	 * @return the new instance, never null.
+	 */
+//	public static MoneyCurrency of(com.ibm.icu.util.Currency currency) {
+//		String key = ISO_NAMESPACE + ':' + currency.getCurrencyCode();
+//		MoneyCurrency cachedItem = CACHED.get(key);
+//		if (cachedItem == null) {
+//			cachedItem = new ICUCurrencyAdapter(currency);
+//			CACHED.put(key, cachedItem);
+//		}
+//		return cachedItem;
+//	}
+//	
+	/**
+	 * Access a new instance based on the ISO currency code. The code must
+	 * return a {@link Currency} when passed to
+	 * {@link Currency#getInstance(String)}.
+	 * 
+	 * @param currencyCode
+	 *            the ISO currency code, not null.
+	 * @return the corresponding {@link MonetaryCurrency} instance.
+	 */
+	public static MoneyCurrency of(String currencyCode) {
+		return of(Currency.getInstance(currencyCode));
+	}
+
+	/**
+	 * Access a new instance based on the ISO currency code. The code must
+	 * return a {@link Currency} when passed to
+	 * {@link Currency#getInstance(String)}.
+	 * 
+	 * @param namespace
+	 *            the target namespace.
+	 * @param currencyCode
+	 *            the ISO currency code, not null.
+	 * @return the corresponding {@link MonetaryCurrency} instance.
+	 */
+	public static MoneyCurrency of(String namespace, String currencyCode) {
+		String key = namespace + ':' + currencyCode;
+		MoneyCurrency cu = CACHED.get(key);
+		if (cu == null && namespace.equals(ISO_NAMESPACE)) {
+			return of(currencyCode);
+		}
+		return cu;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#isVirtual()
+	 */
+	
+	public boolean isVirtual() {
+		return virtual;
+	}
+
+	/**
+	 * Get the namepsace of this {@link CurrencyUnit}, returns 'ISO-4217'.
+	 */
+	
+	public String getNamespace() {
+		return namespace;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#getValidFrom()
+	 */
+	
+	public Long getValidFrom() {
+		return validFrom;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#getValidUntil()
+	 */
+	
+	public Long getValidUntil() {
+		return validUntil;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#getCurrencyCode()
+	 */
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#getNumericCode()
+	 */
+	
+//	public int getNumericCode() {
+//		return numericCode;
+//	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#getDefaultFractionDigits()
+	 */
+	
+//	public int getDefaultFractionDigits() {
+//		return defaultFractionDigits;
+//	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.money.CurrencyUnit#isLegalTender()
+	 */
+	
+	public boolean isLegalTender() {
+		return legalTender;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Comparable#compareTo(java.lang.Object)
+	 */
+	public int compareTo(CurrencyUnit currency) {
+		int compare = getNamespace().compareTo(currency.getNamespace());
+		if (compare == 0) {
+			compare = getCurrencyCode().compareTo(currency.getCurrencyCode());
+		}
+		if (compare == 0) {
+			if (validFrom == null && currency.getValidFrom() != null) {
+				compare = -1;
+			} else if (validFrom != null && currency.getValidFrom() == null) {
+				compare = 1;
+			} else if (validFrom != null) {
+				compare = validFrom.compareTo(currency.getValidFrom());
+			}
+		}
+		if (compare == 0) {
+			if (validUntil == null && currency.getValidUntil() != null) {
+				compare = -1;
+			} else if (validUntil != null && currency.getValidUntil() == null) {
+				compare = 1;
+			} else if (validUntil != null) {
+				compare = validUntil.compareTo(currency.getValidUntil());
+			}
+		}
+		return compare;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	
+	public String toString() {
+		if (ISO_NAMESPACE.equals(namespace)) {
+			return currencyCode;
+		}
+		return namespace + ':' + currencyCode;
+	}
+
+	/**
+	 * Builder class that supports building complex instances of
+	 * {@link MoneyCurrency}.
+	 * 
+	 * @author Anatole Tresch
+	 */
+	public static final class Builder {
+		/** namespace for this currency. */
+		private String namespace;
+		/** currency code for this currency. */
+		private String currencyCode;
+		/** numeric code, or -1. */
+		private int numericCode = -1;
+		/** fraction digits, or -1. */
+		private int defaultFractionDigits = -1;
+		/** valid from, or {@code null}. */
+		private Long validFrom;
+		/** valid until, or {@code null}. */
+		private Long validUntil;
+		/** true, if legal tender. */
+		private boolean legalTender = true;
+		/** true for virtual currencies. */
+		private boolean virtual = false;
+
+		/**
+		 * Creates a new {@link Builder}.
+		 */
+		public Builder() {
+		}
+
+		/**
+		 * Creates a new {@link Builder}, starting with the according ISO
+		 * currency.
+		 * 
+		 * @param currencyCode
+		 *            the ISO currency code.
+		 */
+		public Builder(String currencyCode) {
+			this(ISO_NAMESPACE, currencyCode);
+		}
+
+		/**
+		 * Creates a new {@link Builder}, starting with the namespace and code
+		 * given.
+		 * 
+		 * @param namespace
+		 *            the taregt namespace
+		 * @param currencyCode
+		 *            the currency code
+		 */
+		public Builder(String namespace, String currencyCode) {
+			setNamespace(namespace);
+			setCurrencyCode(currencyCode);
+		}
+
+		/**
+		 * Set the namespace.
+		 * 
+		 * @param namespace
+		 *            the namespace, not null
+		 * @return the builder, for chaining
+		 */
+		public Builder setNamespace(String namespace) {
+			if (namespace == null) {
+				throw new IllegalArgumentException("namespace may not be null.");
+			}
+			this.namespace = namespace;
+			return this;
+		}
+
+		/**
+		 * Set the currency code.
+		 * 
+		 * @param namespace
+		 *            the currency code, not null
+		 * @return the builder, for chaining
+		 */
+		public Builder setCurrencyCode(String currencyCode) {
+			if (currencyCode == null) {
+				throw new IllegalArgumentException(
+						"currencyCode may not be null.");
+			}
+			this.currencyCode = currencyCode;
+			return this;
+		}
+
+		/**
+		 * Set the default fraction digits.
+		 * 
+		 * @param defaultFractionDigits
+		 *            the default fraction digits
+		 * @return the builder, for chaining
+		 */
+		public Builder setDefaultFractionDigits(int defaultFractionDigits) {
+			if (defaultFractionDigits < -1) {
+				throw new IllegalArgumentException(
+						"Invalid value for defaultFractionDigits: "
+								+ defaultFractionDigits);
+			}
+			this.defaultFractionDigits = defaultFractionDigits;
+			return this;
+		}
+
+		/**
+		 * Set the numeric currency code.
+		 * 
+		 * @param numericCode
+		 *            the numeric currency code
+		 * @return the builder, for chaining
+		 */
+		public Builder setNumericCode(int numericCode) {
+			if (numericCode < -1) {
+				throw new IllegalArgumentException(
+						"Invalid value for numericCode: " + numericCode);
+			}
+			this.numericCode = numericCode;
+			return this;
+		}
+
+		/**
+		 * Sets the start UTC timestamp for the currenciy's validity.
+		 * 
+		 * @param validFrom
+		 *            the start UTC timestamp
+		 * @return the builder, for chaining
+		 */
+		public Builder setValidFrom(Long validFrom) {
+			this.validFrom = validFrom;
+			return this;
+		}
+
+		/**
+		 * Sets the end UTC timestamp for the currenciy's validity.
+		 * 
+		 * @param validUntil
+		 *            the ending UTC timestamp
+		 * @return the builder, for chaining
+		 */
+		public Builder setValidUntil(Long validUntil) {
+			this.validUntil = validUntil;
+			return this;
+		}
+
+		/**
+		 * Sets the legal tender attribute.
+		 * 
+		 * @param legalTender
+		 *            true, if the currency is a legal tender
+		 * @return the builder, for chaining
+		 */
+		public Builder setLegalTender(boolean legalTender) {
+			this.legalTender = legalTender;
+			return this;
+		}
+
+		/**
+		 * Sets the virtual attribute.
+		 * 
+		 * @param virtual
+		 *            true, if the currency is a virtual currency.
+		 * @return the builder, for chaining
+		 */
+		public Builder setVirtual(boolean virtual) {
+			this.virtual = virtual;
+			return this;
+		}
+
+		/**
+		 * Get the current namespace attribute set.
+		 * 
+		 * @return the namespace value, or null.
+		 */
+		public String getNamespace() {
+			return this.namespace;
+		}
+
+		/**
+		 * Get the current currency code attribute set.
+		 * 
+		 * @return the currency code value, or null.
+		 */
+		public String getCurrencyCode() {
+			return this.currencyCode;
+		}
+
+		/**
+		 * Get the current fraction digits attribute set.
+		 * 
+		 * @return the currency fraction digits value.
+		 */
+		public int getDefaultFractionDigits() {
+			return this.defaultFractionDigits;
+		}
+
+		/**
+		 * Get the current numeric code attribute set.
+		 * 
+		 * @return the numeric code value.
+		 */
+		public int getNumericCode() {
+			return this.numericCode;
+		}
+
+		/**
+		 * Get the starting validity period timestamp.
+		 * 
+		 * @return the starting validity period tiemstamp, or null..
+		 */
+		public Long getValidFrom() {
+			return this.validFrom;
+		}
+
+		/**
+		 * Get the ending validity period timestamp.
+		 * 
+		 * @return the ending validity period tiemstamp, or null..
+		 */
+		public Long getValidUntil() {
+			return this.validUntil;
+		}
+
+		/**
+		 * Access the legal tender attribute.
+		 * 
+		 * @return the attribute value.
+		 */
+		public boolean isLegalTender() {
+			return this.legalTender;
+		}
+
+		/**
+		 * Access the virtual attribute.
+		 * 
+		 * @return the attribute value.
+		 */
+		public boolean isVirtual() {
+			return this.virtual;
+		}
+
+		/**
+		 * Checks if this {@link Builder} instance can create a
+		 * {@link MoneyCurrency}.
+		 * 
+		 * @see #build()
+		 * @return true, if the builder can build.
+		 */
+		public boolean isBuildable() {
+			return namespace != null && currencyCode != null;
+		}
+
+		/**
+		 * Builds a new currency instance, the instance build is not cached
+		 * internally.
+		 * 
+		 * @see #build(boolean)
+		 * @return a new instance of {@link MoneyCurrency}.
+		 */
+		public MoneyCurrency build() {
+			return build(true);
+		}
+
+		/**
+		 * Builds a new currency instance, which ia additinoally stored to the
+		 * internal cache for reuse.
+		 * 
+		 * @param cache
+		 *            flag to optionally store the instance created into the
+		 *            locale cache.
+		 * @return a new instance of {@link MoneyCurrency}.
+		 */
+		public MoneyCurrency build(boolean cache) {
+			if (!isBuildable()) {
+				throw new IllegalStateException(
+						"Can not build CurrencyUnitImpl.");
+			}
+			if (cache) {
+				if (validUntil != null) {
+					LOGGER.warning("CurrencyUnit build: Can only cache currencies that have no validity constraints.");
+					cache = false;
+				}
+				if (validFrom != null) {
+					if (validFrom.longValue() > System.currentTimeMillis()) {
+						LOGGER.warning("CurrencyUnit build: Can only cache currencies that are already valid.");
+						cache = false;
+					}
+				}
+			}
+			if (cache) {
+				String key = namespace + ':' + currencyCode;
+				MoneyCurrency current = CACHED.get(key);
+				if (current == null) {
+					current = new MoneyCurrency(namespace, currencyCode,
+							numericCode, defaultFractionDigits, validFrom,
+							validUntil, legalTender, virtual);
+					CACHED.put(key, current);
+				}
+				return current;
+			}
+			return new MoneyCurrency(namespace, currencyCode, numericCode,
+					defaultFractionDigits, validFrom, validUntil, legalTender,
+					virtual);
+		}
+	}
+
+	/**
+	 * Adapter that implements the new {@link CurrencyUnit} interface using the
+	 * JDK's {@link Currency}.
+	 * <p>
+	 * This adapter will be removed in the final platform implementation.
+	 * 
+	 * @author Anatole Tresch
+	 * @author Werner Keil
+	 */
+	private final static class JDKCurrencyAdapter extends MoneyCurrency
+			implements Localizable {
+
+		/**
+		 * serialVersionUID.
+		 */
+		private static final long serialVersionUID = -2523936311372374236L;
+
+		/**
+		 * ISO 4217 currency code for this currency.
+		 * 
+		 * @serial
+		 */
+		private final Currency currency;
+
+		/**
+		 * Private constructor.
+		 * 
+		 * @param currency
+		 */
+		private JDKCurrencyAdapter(Currency currency) {
+			super(currency);
+			this.currency = currency;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Object#toString()
+		 */
+		
+		public String toString() {
+			return ISO_NAMESPACE + ':' + getCurrencyCode();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see Localizable#getDisplayName(java.util.Locale)
+		 */
+		public String getDisplayName(Locale locale) {
+			//return currency.getName(locale, nameStyle, isChoiceFormat) (locale);
+			return currency.getName(ULocale.forLocale(locale), LONG_NAME, new boolean[1]);
+		}
+
+	}
+	
+	/**
+	 * Adapter that implements the new {@link CurrencyUnit} interface using the
+	 * JDK's {@link Currency}.
+	 * <p>
+	 * This adapter will be removed in the final platform implementation.
+	 * 
+	 * @author Werner Keil
+	 */
+	private final static class ICUCurrencyAdapter extends MoneyCurrency
+			implements Localizable {
+
+		/**
+		 * serialVersionUID.
+		 */
+		private static final long serialVersionUID = -2523936311372374236L;
+
+		/**
+		 * ISO 4217 currency code for this currency.
+		 * 
+		 * @serial
+		 */
+		private final com.ibm.icu.util.Currency currency;
+
+		/**
+		 * Private constructor.
+		 * 
+		 * @param currency
+		 */
+		private ICUCurrencyAdapter(com.ibm.icu.util.Currency currency) {
+			super(ISO_NAMESPACE, currency.getCurrencyCode(), -1, currency.getDefaultFractionDigits(),
+					null, null, true, false);
+			this.currency = currency;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Object#toString()
+		 */
+		
+		public String toString() {
+			return ISO_NAMESPACE + ':' + getCurrencyCode();
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see javax.money.Localizable#getDisplayName(java.util.Locale)
+		 */
+		
+		public String getDisplayName(Locale locale) {
+			return currency.getName(ULocale.forLocale(locale), LONG_NAME, new boolean[1]);
+		}
+
+	}
+
+	public String getDisplayName(Locale locale) {
+		return getName(ULocale.forLocale(locale), LONG_NAME, new boolean[1]);
+	}
+
+	public int getNumericCode() {
+		return -1;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyExchangeRate.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyExchangeRate.java
new file mode 100644
index 0000000..395796c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyExchangeRate.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2012, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import java.util.Enumeration;
+
+import org.eclipse.uomo.business.internal.ExchangeRate;
+import org.eclipse.uomo.business.internal.ExchangeRateType;
+
+import com.ibm.icu.util.Currency;
+
+/**
+ * @version 0.3
+ * @author Werner Keil
+ * 
+ */
+public class MoneyExchangeRate implements ExchangeRate {
+
+	private final ExchangeRateType type;
+
+	private final Currency source;
+
+	private final Currency target;
+
+	private final Number factor;
+
+	public MoneyExchangeRate(Currency source, Currency target, Number factor) {
+		this.source = source;
+		this.target = target;
+		this.factor = factor;
+		type = ExchangeRateType.of("DEFAULT");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getExchangeRateType()
+	 */
+	public ExchangeRateType getExchangeRateType() {
+		return type;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getSource()
+	 */
+	public Currency getSource() {
+		return source;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getTarget()
+	 */
+	public Currency getTarget() {
+		return target;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getFactor()
+	 */
+	public Number getFactor() {
+		return factor;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getValidFrom()
+	 */
+	public Long getValidFrom() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getValidUntil()
+	 */
+	public Long getValidUntil() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#isValid()
+	 */
+	public boolean isValid() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getProvider()
+	 */
+	public String getProvider() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getExchangeRateChain()
+	 */
+	public ExchangeRate[] getExchangeRateChain() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#isDerived()
+	 */
+	public boolean isDerived() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#isIdentity()
+	 */
+	public boolean isIdentity() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.business.money.ExchangeRate#getAttribute(java.lang.String
+	 * , java.lang.Class)
+	 */
+	public <T> T getAttribute(String key, Class<T> type) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.business.money.ExchangeRate#getAttributeKeys()
+	 */
+	public Enumeration<String> getAttributeKeys() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.business.money.ExchangeRate#getAttributeType(java.lang
+	 * .String)
+	 */
+	public Class<?> getAttributeType(String key) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyUnit.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyUnit.java
new file mode 100644
index 0000000..c8f1804
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/money/MoneyUnit.java
@@ -0,0 +1,489 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.money;
+
+import static org.eclipse.uomo.business.money.MonetaryUnits.ISO_NAMESPACE;
+
+import java.math.BigInteger;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.impl.AlternateUnit;
+import org.eclipse.uomo.units.impl.ProductUnit;
+import org.eclipse.uomo.units.impl.TransformedUnit;
+import org.eclipse.uomo.units.impl.converter.AddConverter;
+import org.eclipse.uomo.units.impl.converter.MultiplyConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.eclipse.uomo.business.internal.CurrencyUnit;
+import org.eclipse.uomo.business.internal.Localizable;
+import org.eclipse.uomo.business.types.IMoney;
+import org.eclipse.uomo.core.IName;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.ULocale;
+
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.2.6, $Date: 2013-05-20
+ * @param <Q> the monetary quantity
+ * 
+ */
+public class MoneyUnit<Q extends IMoney> extends Currency implements
+		Unit<IMoney>, IName, CurrencyUnit, Localizable, Comparable<CurrencyUnit> {
+// TODO use JSR 354
+	/**
+     * 
+     */
+	private static final long serialVersionUID = 8524573975644908457L;
+	
+	/** namespace for this currency. */
+	private final String namespace;
+	/** valid from, or {@code null}. */
+	private final Long validFrom;
+	/** valid until, or {@code null}. */
+	private final Long validUntil;
+	/** true, if legal tender. */
+	private final boolean legalTender;
+	/** true, if it is a virtual currency. */
+	private final boolean virtual;
+	
+	protected MoneyUnit(String theCode, String namespace, 
+			Long validFrom, Long validUntil,
+			boolean legalTender, boolean virtual) {
+		super(theCode);
+		this.namespace = namespace;
+		this.validFrom = validFrom;
+		this.validUntil = validUntil;
+		this.legalTender = legalTender;
+		this.virtual = virtual;
+	}
+	
+	protected MoneyUnit(String theISOCode) {
+		this(theISOCode, ISO_NAMESPACE, null, null, true, false);
+	}
+
+	/**
+	 * The Canadian Dollar currency unit.
+	 */
+	public static final MoneyUnit<IMoney> CAD = new MoneyUnit<IMoney>("CAD"); //$NON-NLS-1$
+
+	/**
+	 * The China Yan currency.
+	 */
+	public static final MoneyUnit<IMoney> CNY = new MoneyUnit<IMoney>("CNY"); //$NON-NLS-1$
+
+	/**
+	 * The Euro currency.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static final MoneyUnit EUR = new MoneyUnit<IMoney>("EUR"); //$NON-NLS-1$
+
+	/**
+	 * The British Pound currency.
+	 */
+	public static final MoneyUnit<IMoney> GBP = new MoneyUnit<IMoney>("GBP"); //$NON-NLS-1$
+
+	/**
+	 * The Japanese Yen currency.
+	 */
+	public static final MoneyUnit<IMoney> JPY = new MoneyUnit<IMoney>("JPY"); //$NON-NLS-1$
+
+	/**
+	 * The Korean Republic Won currency.
+	 */
+	public static final MoneyUnit<IMoney> KRW = new MoneyUnit<IMoney>("KRW"); //$NON-NLS-1$
+
+	/**
+	 * The Taiwanese dollar currency.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static final MoneyUnit TWD = new MoneyUnit<IMoney>("TWD"); //$NON-NLS-1$
+
+	/**
+	 * Holds the dimensionless unit <code>ONE</code>.
+	 */
+	public static final ProductUnit<IMoney> ONE = new ProductUnit<IMoney>();
+
+	/**
+	 * The United State dollar currency.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static final MoneyUnit USD = new MoneyUnit<IMoney>("USD"); //$NON-NLS-1$
+
+	/**
+	 * Returns the result of adding an offset to this unit. The returned unit is
+	 * convertible with all units that are convertible with this unit.
+	 * 
+	 * @param offset
+	 *            the offset added (expressed in this unit, e.g.
+	 *            <code>CELSIUS = KELVIN.add(273.15)</code>).
+	 * @return <code>this.transform(new AddConverter(offset))</code>
+	 */
+	public final Unit<IMoney> add(double offset) {
+		if (offset == 0)
+			return this;
+		return transform(new AddConverter(offset));
+	}
+
+	/**
+	 * Returns a metric unit equivalent to this unscaled metric unit but used in
+	 * expressions to distinguish between quantities of a different nature but
+	 * of the same dimensions.
+	 * 
+	 * <p>
+	 * Examples of alternate units:[code] Unit<Angle> RADIAN =
+	 * ONE.alternate("rad"); Unit<Force> NEWTON =
+	 * METRE.times(KILOGRAM).divide(SECOND.pow(2)).alternate("N");
+	 * Unit<Pressure> PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa");
+	 * [/code]
+	 * </p>
+	 * 
+	 * @param <Q>
+	 *            the type of the quantity measured by the new alternate unit.
+	 * 
+	 * @param symbol
+	 *            the new symbol for the alternate unit.
+	 * @return the alternate unit.
+	 * @throws UnsupportedOperationException
+	 *             if this unit is not an unscaled metric unit.
+	 * @throws IllegalArgumentException
+	 *             if the specified symbol is already associated to a different
+	 *             unit.
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<IMoney> alternate(String symbol) {
+		return new AlternateUnit(symbol, this);
+	}
+
+	public <T extends Quantity<T>> Unit<T> asType(Class<T> type) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * Returns the result of dividing this unit by an approximate divisor.
+	 * 
+	 * @param divisor
+	 *            the approximate divisor.
+	 * @return <code>this.transform(new MultiplyConverter(1.0 / divisor))</code>
+	 */
+	public final Unit<IMoney> divide(double divisor) {
+		if (divisor == 1)
+			return this;
+		return transform(new MultiplyConverter(1.0 / divisor));
+	}
+
+	/**
+	 * Returns the result of dividing this unit by an exact divisor.
+	 * 
+	 * @param divisor
+	 *            the exact divisor. (e.g.
+	 *            <code>QUART = GALLON_LIQUID_US.divide(4)</code>).
+	 * @return <code>this.transform(new RationalConverter(1 , divisor))</code>
+	 */
+	public final Unit<?> divide(long divisor) {
+		if (divisor == 1)
+			return this;
+		return (Unit<?>) transform(new RationalConverter(BigInteger.ONE,
+				BigInteger.valueOf(divisor)));
+	}
+
+	public UnitConverter getConverterTo(Unit<IMoney> that)
+			throws UnconvertibleException {
+		return new MoneyConverter(this, that, 1);
+	}
+
+	public UnitConverter getConverterToAny(Unit<?> that)
+			throws IncommensurableException, UnconvertibleException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Dimension getDimension() {
+		return IMoney.DIMENSION;
+	}
+
+	public Map<Unit<?>, Integer> getProductUnits() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	private boolean isRationalFactor() {
+		// if (!(this instanceof TransformedUnit<?>))
+		// return false;
+		// TransformedUnit<Q> tu = (TransformedUnit<Q>) this;
+		// return tu.getParentUnit().equals(ONE) &&
+		// (tu.getConverterTo(tu.toMetric()) instanceof RationalConverter);
+		return true;
+	}
+
+	/**
+	 * Returns the inverse of this unit.
+	 * 
+	 * @return <code>1 / this</code>
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<?> inverse() {
+		if (this.equals(ONE))
+			return this;
+		if (this.isRationalFactor())
+			return this.transform(this.getConverterTo((Unit) ONE).inverse());
+		return ProductUnit.getQuotientInstance(ONE, this);
+	}
+
+	public boolean isCompatible(Unit<?> that) {
+		return (this == that)
+				|| this.toMetric().equals(that.getSystemUnit())
+				|| (!"".equals(this.getDimension().toString()) && this.getDimension().equals(that.getDimension())); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the result of multiplying this unit by an exact factor.
+	 * 
+	 * @param factor
+	 *            the exact scale factor (e.g.
+	 *            <code>KILOMETRE = METRE.multiply(1000)</code>).
+	 * @return <code>this.transform(new RationalConverter(factor, 1))</code>
+	 */
+	final Unit<IMoney> multiply(long factor) {
+		if (factor == 1)
+			return this;
+		return transform(new RationalConverter(BigInteger.valueOf(factor),
+				BigInteger.ONE));
+	}
+
+	/**
+	 * Returns the result of multiplying this unit by a an approximate factor.
+	 * 
+	 * @param factor
+	 *            the approximate factor (e.g.
+	 *            <code>ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31)</code>
+	 *            ).
+	 * @return <code>this.transform(new MultiplyConverter(factor))</code>
+	 */
+	public final Unit<IMoney> multiply(double factor) {
+		if (factor == 1)
+			return this;
+		return transform(new MultiplyConverter(factor));
+	}
+
+	/**
+	 * Returns the product of this unit with the one specified.
+	 * 
+	 * @param that
+	 *            the unit multiplicand.
+	 * @return <code>this * that</code>
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<?> multiply(Unit<?> that) {
+		if (this.equals(ONE))
+			return that;
+		if (that.equals(ONE))
+			return this;
+		if (this.isRationalFactor())
+			return that.transform(this.getConverterTo(ONE));
+		if (((MoneyUnit<?>) that).isRationalFactor())
+			return this.transform(that.getConverterTo((Unit) ONE));
+		return ProductUnit.getProductInstance(this, (AbstractUnit<?>) that);
+	}
+
+	/**
+	 * Returns a unit equals to this unit raised to an exponent.
+	 * 
+	 * @param n
+	 *            the exponent.
+	 * @return the result of raising this unit to the exponent.
+	 */
+	public final Unit<?> pow(int n) {
+		if (n > 0)
+			return this.multiply(this.pow(n - 1));
+		else if (n == 0)
+			return ONE;
+		else
+			// n < 0
+			return ONE.divide(this.pow(-n));
+	}
+
+	/**
+	 * Returns a unit equals to the given root of this unit.
+	 * 
+	 * @param n
+	 *            the root's order.
+	 * @return the result of taking the given root of this unit.
+	 * @throws ArithmeticException
+	 *             if <code>n == 0</code> or if this operation would result in
+	 *             an unit with a fractional exponent.
+	 */
+	public final Unit<?> root(int n) {
+		if (n > 0)
+			return ProductUnit.getRootInstance(this, n);
+		else if (n == 0)
+			throw new ArithmeticException("Root's order of zero"); //$NON-NLS-1$
+		else
+			// n < 0
+			return ONE.divide(this.root(-n));
+	}
+
+	protected Unit<IMoney> toMetric() {
+		return this;
+	}
+
+	/**
+	 * Returns the unit derived from this unit using the specified converter.
+	 * The converter does not need to be linear. For example:[code]
+	 * Unit<Dimensionless> DECIBEL = Unit.ONE.transform( new
+	 * LogConverter(10).inverse().concatenate( new RationalConverter(1, 10)));
+	 * [/code]
+	 * 
+	 * @param operation
+	 *            the converter from the transformed unit to this unit.
+	 * @return the unit after the specified transformation.
+	 */
+	@SuppressWarnings("unchecked")
+	public final Unit<IMoney> transform(UnitConverter operation) {
+		if (this instanceof Unit<?>) {
+			Unit<IMoney> tf = this;
+			Unit<?> parent = (Unit<?>) ((TransformedUnit<?>) tf)
+					.getParentUnit();
+			UnitConverter toParent = ((TransformedUnit<?>) tf).toParentUnit();
+			if (toParent == null)
+				return (Unit<IMoney>) parent;
+			UnitConverter toParentConcat = toParent.concatenate(operation);
+			if (toParentConcat == AbstractConverter.IDENTITY)
+				return (Unit<IMoney>) parent;
+			return new TransformedUnit<IMoney>((Unit<IMoney>) parent,
+					(AbstractConverter) toParentConcat);
+		}
+		if (operation == AbstractConverter.IDENTITY)
+			return this;
+		return new TransformedUnit<IMoney>(this, (AbstractConverter) operation);
+	}
+
+	/**
+	 * Returns the quotient of this unit with the one specified.
+	 * 
+	 * @param that
+	 *            the unit divisor.
+	 * @return <code>this / that</code>
+	 */
+	public final Unit<?> divide(Unit<?> that) {
+		return (Unit<?>) this.multiply(that.inverse());
+	}
+
+	public String getName() {
+		return getName(ULocale.getDefault(), LONG_NAME, new boolean[] { false });
+	}
+
+	public Unit<IMoney> getSystemUnit() {
+		return toMetric();
+	}
+	 
+	/**
+	 * Get the namespace of this {@link CurrencyUnit}, default 'ISO-4217'.
+	 */
+	public String getNamespace() {
+		return namespace;
+	}
+	 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see CurrencyUnit#isLegalTender()
+	 */
+	public boolean isLegalTender() {
+		return legalTender;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see CurrencyUnit#isVirtual()
+	 */
+	public boolean isVirtual() {
+		return virtual;
+	}
+	 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see CurrencyUnit#getValidFrom()
+	 */
+	
+	public Long getValidFrom() {
+		return validFrom;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see CurrencyUnit#getValidUntil()
+	 */
+	
+	public Long getValidUntil() {
+		return validUntil;
+	}
+
+	public int compareTo(CurrencyUnit currency) {
+		int compare = getNamespace().compareTo(currency.getNamespace());
+		if (compare == 0) {
+			compare = getCurrencyCode().compareTo(currency.getCurrencyCode());
+		}
+		if (compare == 0) {
+			if (validFrom == null && currency.getValidFrom() != null) {
+				compare = -1;
+			} else if (validFrom != null && currency.getValidFrom() == null) {
+				compare = 1;
+			} else if (validFrom != null) {
+				compare = validFrom.compareTo(currency.getValidFrom());
+			}
+		}
+		if (compare == 0) {
+			if (validUntil == null && currency.getValidUntil() != null) {
+				compare = -1;
+			} else if (validUntil != null && currency.getValidUntil() == null) {
+				compare = 1;
+			} else if (validUntil != null) {
+				compare = validUntil.compareTo(currency.getValidUntil());
+			}
+		}
+		return compare;
+	}
+	
+	/**
+	 * Access a new instance based on the ISO currency code. The code must
+	 * return a {@link Currency} when passed to
+	 * {@link Currency#getInstance(String)}.
+	 * 
+	 * @param currencyCode
+	 *            the ISO currency code, not null.
+	 * @return the corresponding {@link MonetaryCurrency} instance.
+	 */
+	public static MoneyUnit of(String currencyCode) {
+		return new MoneyUnit(currencyCode);
+	}
+
+	public String getDisplayName(Locale locale) {
+		return getName(ULocale.forLocale(locale), LONG_NAME, new boolean[1]);
+	}
+
+	public int getNumericCode() {
+		return -1;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTHelper.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTHelper.java
new file mode 100644
index 0000000..20b6850
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTHelper.java
@@ -0,0 +1,342 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types;
+
+import java.util.*;
+
+import org.eclipse.uomo.business.types.impl.PercentAmount;
+
+import com.ibm.icu.math.BigDecimal;
+import com.ibm.icu.math.MathContext;
+
+/**
+ * This is a helper class supporting the other classes in this package
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+
+public abstract class BDTHelper {
+	public static enum Operation {
+		EQ, // equal
+		LT, // less than
+		LE, // less than or equal
+		GT, // greater than
+		GE, // greater than or equal
+		NE; // not equal
+	}
+	
+	// Define a MathContext object providing 20 digits
+	public static MathContext MATH_CONTEXT = new MathContext(20);
+
+	static HashMap<String, String> s_countryTable = null;
+
+	public static Map<String, String> getCountries() {
+		return s_countryTable;
+	}
+
+	static {
+		s_countryTable = new HashMap<String, String>();
+
+		s_countryTable.put("CA", null);
+		s_countryTable.put("US", null);
+
+	}
+
+	public static final String DEFAULT_COUNTRY = "CA"; // Canada is default
+
+	// The following tables will be loaded from a database
+
+	// static HashMap<String, Currency> s_currencyTable = null; // table of
+	// currencies
+	//
+	// static {
+	//
+	// s_currencyTable = new HashMap<String, Currency>();
+	//
+	// // Precision of -1 means undefined precision
+	//
+	// AddCurrency("CAD", 2); // Canadian dollars
+	//
+	// AddCurrency("USD", 2); // US dollars
+	//
+	// AddCurrency("GBP", 2); // Great Britain Pounds
+	//
+	// AddCurrency("FRF", 2); // French Francs
+	//
+	// AddCurrency("ITL", 0); // Italian Lire
+	//
+	// AddCurrency("BHD", 3); // Bahraini Dinar
+	//
+	// AddCurrency("XAU", -1); // Euro Gold
+	//
+	// }
+
+	static HashMap<String, IMarket> s_marketTable = new HashMap<String, IMarket>(); // table
+																					// of
+	/**
+	 * Dummy constructor for BDTHelper - ensures no instance can be built
+	 */
+
+	private BDTHelper() {
+	}
+
+	/**
+	 * Add a currency to s_currencyTable (at initialization time)
+	 * 
+	 * @param s
+	 *            java.lang.String
+	 * @param precision
+	 *            int
+	 */
+	// public static void AddCurrency(String s, int precision) {
+	// Currency cur = new Currency(s, precision);
+	// s_currencyTable.put(s, cur);
+	// }
+	/**
+	 * Add a Market to s_marketTable (at initialization time)
+	 * 
+	 * @param s1
+	 *            java.lang.String - code
+	 * @param s2
+	 *            java.lang.String - timezone
+	 * @param s3
+	 *            java.lang.String - country_code
+	 * @param s4
+	 *            java.lang.String - quote_currency
+	 */
+	// public static void AddMarket(String s1, String s2, String s3, String s4)
+	// {
+	// IMarket mkt = Market.CreateMarket(s1, s2, s3, s4);
+	// mkt.setHolidays(null);
+	//
+	// s_marketTable.put(s1, mkt);
+	// }
+	/**
+	 * Add a Market to s_marketTable (at initialization time)
+	 * 
+	 * @param s1
+	 *            java.lang.String - code
+	 * @param s2
+	 *            java.lang.String - timezone
+	 * @param s3
+	 *            java.lang.List - vector of close indicator, open time, close
+	 *            time
+	 */
+	// public static void AddMarketTimes(String s1, String s2, List list) {
+	//
+	// IMarket mkt = Market.Get(s1);
+	//
+	// HashMap<String, List> hm = null;
+	//
+	// hm = mkt.getTimes();
+	// if (hm == null) {
+	// hm = new HashMap<String, List>();
+	// mkt.setTimes(hm);
+	// }
+	// hm.put(s2, list);
+	//
+	// }
+
+	/**
+	 * Use value (BigDecimal) to calculate vulgar fraction, and set fields. This
+	 * logic uses the actual number of digits to the right of the decimal point.
+	 * Thus .50 will be expressed as 2/4, rather than 1/2.
+	 * 
+	 * @return int[]
+	 * @param bd
+	 *            java.math.BigDecimal
+	 * @throws BDTypeException
+	 */
+	static int[] calcVulgarFrac(BigDecimal bd) throws BDTypeException {
+
+		int[] parts = { 0, 0, 0 };
+		parts[0] = bd.intValue();
+		BigDecimal temp = new BigDecimal(parts[0]);
+		BigDecimal temp2 = bd.subtract(temp, MATH_CONTEXT);
+		String s = temp2.toString();
+		int len = s.length() - s.indexOf('.') - 1; // determine no. of places of
+													// decimals
+		BigDecimal two = new BigDecimal(2);
+		BigDecimal pow = two.pow(BigDecimal.valueOf(len)); // we now have correct power of 2
+		parts[2] = pow.intValue();
+		pow = pow.multiply(temp2, MATH_CONTEXT);
+		try {
+			parts[1] = pow.intValueExact();
+		} catch (ArithmeticException e) {
+			parts[2] = 0; // reset denominator, so value will display as decimal
+			throw new BDTypeException(
+					"Fractional value not divisible by power of 2: " + bd);
+		}
+		;
+		return parts;
+
+	}
+
+	/**
+	 * Generalized compare for exchange rates
+	 * 
+	 * @return boolean
+	 * @param x
+	 *            ExchRate - first exchange rate
+	 * @param y
+	 *            ExchRate - second exchange rate
+	 * @param op
+	 *            int - desired relationship (less than, equal, not equal, etc.)
+	 * @throws BDTypeException
+	 */
+	// static boolean Comp(ExchangeRate x, ExchangeRate y, int op) throws
+	// BDTypeException{
+	// if (x.m_sourceCurrency != y.m_sourceCurrency)
+	// throw new BDTypeException("Source currency mismatch: " +
+	// x.m_sourceCurrency.getAbbrev() + ", " + y.m_sourceCurrency.getAbbrev());
+	// if (x.m_targetCurrency != y.m_targetCurrency)
+	// throw new BDTypeException("Target currency mismatch: " +
+	// x.m_targetCurrency.getAbbrev() + ", " + y.m_targetCurrency.getAbbrev());
+	// switch (op) {
+	// case EQ: return (0 == x.m_value.compareTo(y.m_value));
+	// case NE: return (0 != x.m_value.compareTo(y.m_value));
+	// case LT: return (-1 == x.m_value.compareTo(y.m_value));
+	// case LE: return (1 != x.m_value.compareTo(y.m_value));
+	// case GT: return (1 == x.m_value.compareTo(y.m_value));
+	// case GE: return (-1 != x.m_value.compareTo(y.m_value));
+	// default: throw new BDTypeException("Unknown compare operator: " + op);
+	// }
+	//
+	// }
+	/**
+	 * Generalized compare for monetary amounts
+	 * 
+	 * @return boolean
+	 * @param x
+	 *            Monetary - first monetary amount
+	 * @param y
+	 *            Monetary - second monetary amount
+	 * @param op
+	 *            int - desired relationship (less than, equal, not equal, etc.)
+	 * @throws BDTypeException
+	 */
+	// static boolean Comp(Money x, Money y, int op) throws BDTypeException{
+	// if (x.m_currency != y.m_currency)
+	// throw new BDTypeException("Currency mismatch: " +
+	// x.getCurrAbbr() + ", " + y.getCurrAbbr());
+	// switch (op) {
+	// case EQ: return (0 == x.m_value.compareTo(y.m_value));
+	// case NE: return (0 != x.m_value.compareTo(y.m_value));
+	// case LT: return (-1 == x.m_value.compareTo(y.m_value));
+	// case LE: return (1 != x.m_value.compareTo(y.m_value));
+	// case GT: return (1 == x.m_value.compareTo(y.m_value));
+	// case GE: return (-1 != x.m_value.compareTo(y.m_value));
+	// default: throw new BDTypeException("Unknown compare operator: " + op);
+	// }
+	// }
+	/**
+	 * Generalized compare for Percents
+	 * 
+	 * @return boolean
+	 * @param x
+	 *            Percent - first Percent
+	 * @param y
+	 *            Percent - second Percent
+	 * @param op
+	 *            int - desired relationship (less than, equal, not equal, etc.)
+	 * @throws BDTypeException
+	 */
+	public static boolean comp(PercentAmount x, PercentAmount y, Operation op)
+			throws BDTypeException {
+
+		switch (op) {
+		case EQ:
+			return (0 == x.compareTo(y));
+		case NE:
+			return (0 != x.compareTo(y));
+		case LT:
+			return (-1 == x.compareTo(y));
+		case LE:
+			return (1 != x.compareTo(y));
+		case GT:
+			return (1 == x.compareTo(y));
+		case GE:
+			return (-1 != x.compareTo(y));
+		default:
+			throw new BDTypeException("Unknown compare operator: " + op);
+		}
+
+	}
+
+	/**
+	 * Generalized compare for BigDecimal
+	 * 
+	 * @return boolean
+	 * @param x
+	 *            java.math.BigDecimal - first BigDecimal
+	 * @param y
+	 *            java.math.BigDecimal - second BigDecimal
+	 * @param op
+	 *            int - desired relationship (less than, equal, not equal, etc.)
+	 * @throws BDTypeException
+	 */
+
+	static boolean comp(BigDecimal x, BigDecimal y, Operation op)
+			throws BDTypeException {
+		switch (op) {
+		case EQ:
+			return (0 == x.compareTo(y));
+		case NE:
+			return (0 != x.compareTo(y));
+		case LT:
+			return (-1 == x.compareTo(y));
+		case LE:
+			return (1 != x.compareTo(y));
+		case GT:
+			return (1 == x.compareTo(y));
+		case GE:
+			return (-1 != x.compareTo(y));
+		default:
+			throw new BDTypeException("Unknown compare operator: " + op);
+		}
+
+	}
+
+	/**
+	 * Create an IPrice (MPrice or PCPrice) from a string containing
+	 * code/currency, value and 'P', 'V' or ' ' - all concatenated together. If
+	 * final character is absent, decide based on first 3 chars (code/currency).
+	 * 
+	 * @return IPrice
+	 * @param s
+	 *            java.lang.String
+	 * @throws BDTypeException
+	 */
+	// public static IPrice CreatePrice(String s) throws BDTypeException {
+	// String c = s.substring(0, 3);
+	// String v = s.substring(3);
+	// int len = v.length();
+	//
+	// String last = v.substring(len - 1, len);
+	//
+	// if (last.equals("P") || !last.equals(" ") && !last.equals("V") &&
+	// PCPrice.s_types.containsKey(c))
+	// return new PCPrice(c + v);
+	// else
+	// return new MPrice(c + v);
+	//
+	//
+	//
+	// }
+	/**
+	 * Insert the method's description here. Creation date: (9/27/00 6:02:51 PM)
+	 * 
+	 * @return com.sun.java.util.collections.HashMap
+	 */
+	public static Map<String, IMarket> getMarkets() {
+		return s_marketTable;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTypeException.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTypeException.java
new file mode 100644
index 0000000..dafd4d2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/BDTypeException.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types;
+
+import org.eclipse.uomo.core.UOMoRuntimeException;
+
+
+/**
+ * Basic Data Type Exception class
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @deprecated Try using UOMoRuntimeException directly
+ */
+public class BDTypeException extends UOMoRuntimeException  {
+	final static long serialVersionUID = 362498820763181265L;
+/**
+ * BDTypeException constructor with String.
+ */
+public BDTypeException(String s)  {
+	super(s);
+	
+}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBDType.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBDType.java
new file mode 100644
index 0000000..12ee051
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBDType.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types;
+
+
+/**
+ * This interface indicates that a class is a Basic Data Type
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IBDType extends IBasicType {
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBasicType.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBasicType.java
new file mode 100644
index 0000000..97a1fe6
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IBasicType.java
@@ -0,0 +1,16 @@
+package org.eclipse.uomo.business.types;
+
+/**
+ * This interface indicates that a class is a Basic Data Type
+ * 
+ * @author Werner Keil
+ */
+public interface IBasicType {
+	
+	/**
+	 * This requires that all Basic Data Types implement a serialize method
+	 * 
+	 * @return java.lang.String
+	 */
+	String serialize();	
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMarket.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMarket.java
new file mode 100644
index 0000000..0c8cd78
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMarket.java
@@ -0,0 +1,92 @@
+package org.eclipse.uomo.business.types;
+
+import java.util.*;
+
+import org.eclipse.uomo.core.IName;
+import org.eclipse.uomo.core.ISymbol;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.util.Holiday;
+
+/**
+ * Insert the type's description here. Creation date: (9/20/00 2:35:47 PM)
+ * @version $Revision$, Change date: ($Date$)
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IMarket extends IBDType, IName, ISymbol {
+	/**
+	 * Insert the method's description here. Creation date: (9/26/00 4:55:31 PM)
+	 * 
+	 * @return java.util.HashMap
+	 */
+	Map<Date, Holiday> getHolidays();
+
+	/**
+	 * Insert the method's description here. Creation date: (9/28/00 9:43:08 AM)
+	 * 
+	 * @return java.util.HashMap
+	 */
+	Map<Date, Holiday> getReplHolidays();
+
+	/**
+	 * Insert the method's description here. Creation date: (9/25/00 10:25:18
+	 * AM)
+	 * 
+	 * @return java.util.HashMap
+	 */
+	Map<String, List<Time>> getTimes();
+
+	/**
+	 * Insert the method's description here. Creation date: (9/25/00 4:36:09 PM)
+	 * 
+	 * @return java.lang.String
+	 */
+	String getTimeZone();
+
+	/**
+	 * Returns true if market is open for specified date and FI Type
+	 * 
+	 * @return boolean
+	 */
+	public boolean isOpen(Date date, String fiType);
+
+	/**
+	 * Returns true if market is open for specified time and FI Type
+	 * 
+	 * @return boolean
+	 */
+	public boolean isOpen(Unit<Time> ts, String fiType);
+
+	/**
+	 * Returns true if market is open right now for specified FIType
+	 * 
+	 * @return boolean
+	 */
+	public boolean isOpen(String fiType);
+
+	/**
+	 * Insert the method's description here. Creation date: (9/26/00 4:52:54 PM)
+	 * 
+	 * @param hm
+	 *            java.util.HashMap
+	 */
+	void setHolidays(Map<Date, Holiday> hm);
+
+	/**
+	 * Insert the method's description here. Creation date: (9/26/00 4:52:54 PM)
+	 * 
+	 * @param hm
+	 *            java.util.HashMap
+	 */
+	void setReplHolidays(Map<Date, Holiday> hm);
+
+	/**
+	 * Insert the method's description here. Creation date: (9/25/00 10:25:57
+	 * AM)
+	 * 
+	 * @param hm
+	 *            java.util.HashMap
+	 */
+	void setTimes(Map<String, List<Time>> hm);
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMoney.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMoney.java
new file mode 100644
index 0000000..7f5228c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IMoney.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.business.types;
+
+import static org.eclipse.uomo.business.money.MoneyAmount.UNIT;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.unitsofmeasurement.unit.Dimension;
+
+/**
+ * This interface represents something generally accepted as a medium of
+ * exchange, a measure of value, or a means of payment. The units for money
+ * quantities is of type {@link Currency}.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 3.2 ($Revision: 227 $), $Date: 2010-10-01 00:54:55 +0200 (Fr, 01 Okt 2010) $
+ */
+public interface IMoney extends IBDType, IMeasure<IMoney> {
+
+    /**
+     * Holds the dimension for money quantities (dimension [$]).
+     */
+    public static final Dimension DIMENSION = UNIT.getDimension();
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IPrice.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IPrice.java
new file mode 100644
index 0000000..925682b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/IPrice.java
@@ -0,0 +1,22 @@
+package org.eclipse.uomo.business.types;
+
+/**
+ * This interfaces includes Monetary Price and Percent Price.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IPrice  extends IBDType {
+
+
+/**
+ * Determine if <code> this </code> IPrice is a multiple of the parameter IPrice.
+ * @return boolean
+ * @param p org.eclipse.uomo.business.types.IPrice
+ */
+public boolean isMultipleOf(IPrice p) ;
+/**
+ * Determine if <code> this </code> IPrice is postive (greater than zero)
+ * @return boolean
+ */
+public boolean isPositive() ;
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/Percent.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/Percent.java
new file mode 100644
index 0000000..d69c76f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/Percent.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2010-2013, Werner Keil, Paul Morrison and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ *    
+ *    TODO move this quantity to Units or PERCENT from SI to another system.
+ */
+package org.eclipse.uomo.business.types;
+
+import org.unitsofmeasurement.quantity.Quantity;
+
+
+/**
+ * Represents a percentage.
+ * The unit for this quantity is "%" (percent).
+ *
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, 2013-01-26
+ */
+public interface Percent extends Quantity<Percent> {
+
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/BDate.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/BDate.java
new file mode 100644
index 0000000..50a0add
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/BDate.java
@@ -0,0 +1,148 @@
+package org.eclipse.uomo.business.types.impl;
+
+import static org.eclipse.uomo.business.types.impl.DataHelper.BDT_DELIM;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.eclipse.uomo.business.types.IBasicType;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+
+/**
+ * Define (non-Java.util) Date class
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public class BDate implements IBasicType {
+	String m_date;
+
+	/**
+	 * Constructor for date with no parameter - use current date in this locale
+	 * - dangerous!
+	 */
+
+	public BDate() {
+
+		Calendar cal = new GregorianCalendar();
+
+		java.util.Date date = cal.getTime();
+
+		TimeStamp ts = new TimeStamp(date.getTime());
+		m_date = ts.serialize().substring(0, 8);
+
+	}
+
+	/**
+	 * Constructor for date with date string (yyyymmdd); optional calendar and
+	 * era are being ignored for now
+	 */
+
+	public BDate(String s) {
+		super();
+		m_date = BuildDate(s);
+	}
+
+	/**
+	 * Constructor for jbdtypes Date using java.sql.Date
+	 */
+
+	public BDate(java.sql.Date dt) {
+		long millis = dt.getTime();
+		TimeStamp ts = new TimeStamp(millis);
+
+		m_date = BuildDate(ts.serialize().substring(0, 8));
+	}
+
+	/**
+	 * Return true if <code>this</code> date is after specified date
+	 * 
+	 * @return boolean
+	 * @param d
+	 *            com.jpmorrsn.jbdtypes.Date
+	 */
+	public boolean after(BDate d) {
+		return Integer.parseInt(this.m_date) > Integer.parseInt(d.m_date);
+	}
+
+	/**
+	 * Return true if <code>this</code> date is before specified date
+	 * 
+	 * @return boolean
+	 * @param d
+	 *            com.jpmorrsn.jbdtypes.Date
+	 */
+	public boolean before(BDate d) {
+		return Integer.parseInt(this.m_date) < Integer.parseInt(d.m_date);
+	}
+
+	/**
+	 * Strip off calendar and era (if any)
+	 * 
+	 * @return java.lang.String
+	 * @param s
+	 *            java.lang.String
+	 */
+	static String BuildDate(String s) {
+		int sp = s.indexOf(BDT_DELIM);
+		if (sp == -1)
+			return s;
+		else
+			return s.substring(0, sp);
+	}
+
+	/**
+	 * Build a TimeStamp using specified TimeTz object
+	 * 
+	 * @return com.jpmorrsn.jbdtypes.TimeStamp
+	 * @param t
+	 *            com.jpmorrsn.jbdtypes.TimeTz
+	 * @throws BDTypeException
+	 */
+	public TimeStamp buildTimeStamp(TimeTz t) throws UOMoRuntimeException {
+
+		return new TimeStamp(m_date + 'T' + t.serialize());
+	}
+
+	/**
+	 * Convert this Date to a java.sql.Date
+	 * 
+	 * @return java.sql.Timestamp
+	 */
+	public java.sql.Date convertToSQL() {
+
+		TimeStamp ts = new TimeStamp(m_date + "T00:00");
+		return new java.sql.Date(ts.getTime());
+
+	}
+
+	/**
+	 * Return true if <code>this</code> date is same as specified date
+	 * 
+	 * @return boolean
+	 * @param d
+	 *            com.jpmorrsn.jbdtypes.Date
+	 */
+	public boolean equals(BDate d) {
+		return Integer.parseInt(this.m_date) == Integer.parseInt(d.m_date);
+	}
+
+	/**
+	 * Display a (non-Java.util) jbdtypes Date object as an 8-byte string
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+
+		return m_date;
+
+	}
+
+	/**
+	 * Create a String from this object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return serialize();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/DataHelper.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/DataHelper.java
new file mode 100644
index 0000000..d4d28ee
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/DataHelper.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types.impl;
+
+import java.util.*;
+
+/**
+ * This is a helper class supporting the other classes in this package
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+
+public abstract class DataHelper {
+	public static final char BDT_DELIM = ';';
+
+	// The following table will be loaded from a database - but not before DCUT3
+
+	static HashMap<String, SimpleTimeZone> s_timeZoneTable = null; // table of
+																	// time
+																	// zones
+
+	static {
+
+		s_timeZoneTable = new HashMap<String, SimpleTimeZone>();
+
+		SimpleTimeZone tz;
+
+		tz = addTimeZone("UTC", 0.0); // UTC - same as GMT
+		tz = addTimeZone("GMT", 0.0); // UTC - same as GMT
+
+		tz = addTimeZone("EST", -5.0); // Eastern Standard Time
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		tz = addTimeZone("NST", -3.5); // Newfoundland
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		tz = addTimeZone("AST", -4.0); // Atlantic Standard Time
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		tz = addTimeZone("CST", -6.0); // Central Standard Time
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		tz = addTimeZone("SST", -6.0); // Central Standard Time (Sask) - no DST
+
+		tz = addTimeZone("MST", -7.0); // Mountain Standard Time
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		tz = addTimeZone("PST", -8.0); // Pacific Standard Time
+		tz.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+		tz.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
+
+		addTimeZone("JST", 9.0); // Japan standard time - no daylight savings
+									// time
+
+	}
+
+	/**
+	 * Dummy constructor for BDTHelper - ensures no instance can be built
+	 */
+
+	private DataHelper() {
+	}
+
+	/**
+	 * Add a currency to s_currencyTable (at initialization time)
+	 * 
+	 * @param s
+	 *            java.lang.String
+	 * @param precision
+	 *            int
+	 */
+	// public static void AddCurrency(String s, int precision) {
+	// Currency cur = new Currency(s, precision);
+	// s_currencyTable.put(s, cur);
+	// }
+	/**
+	 * Add a Market to s_marketTable (at initialization time)
+	 * 
+	 * @param s1
+	 *            java.lang.String - code
+	 * @param s2
+	 *            java.lang.String - timezone
+	 * @param s3
+	 *            java.lang.String - country_code
+	 * @param s4
+	 *            java.lang.String - quote_currency
+	 */
+	// public static void AddMarket(String s1, String s2, String s3, String s4)
+	// {
+	// IMarket mkt = Market.CreateMarket(s1, s2, s3, s4);
+	// mkt.setHolidays(null);
+	//
+	// s_marketTable.put(s1, mkt);
+	// }
+	/**
+	 * Add a Market to s_marketTable (at initialization time)
+	 * 
+	 * @param s1
+	 *            java.lang.String - code
+	 * @param s2
+	 *            java.lang.String - timezone
+	 * @param s3
+	 *            java.lang.List - vector of close indicator, open time, close
+	 *            time
+	 */
+	// public static void AddMarketTimes(String s1, String s2, List list) {
+	//
+	// IMarket mkt = Market.Get(s1);
+	//
+	// HashMap<String, List> hm = null;
+	//
+	// hm = mkt.getTimes();
+	// if (hm == null) {
+	// hm = new HashMap<String, List>();
+	// mkt.setTimes(hm);
+	// }
+	// hm.put(s2, list);
+	//
+	// }
+	/**
+	 * Add a java.util.SimpleTimeZone
+	 * 
+	 * @param String
+	 *            - identifier of time zone
+	 * @param double - hours to be added to UTC to get local time (may be
+	 *        fractional)
+	 * @return SimpleTimeZone
+	 */
+	private static SimpleTimeZone addTimeZone(String id, double off) {
+
+		int offset = (new Double(off * 3600000)).intValue();
+
+		SimpleTimeZone tz = new SimpleTimeZone(offset, id);
+
+		s_timeZoneTable.put(id, tz);
+
+		return tz;
+
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/Market.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/Market.java
new file mode 100644
index 0000000..709cabc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/Market.java
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types.impl;
+
+import java.util.*;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.uomo.business.internal.Messages;
+import org.eclipse.uomo.business.types.BDTHelper;
+import org.eclipse.uomo.business.types.BDTypeException;
+import org.eclipse.uomo.business.types.IMarket;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.util.Holiday;
+
+/**
+ * Market object - object is mutable, but only the holiday table for a market
+ * will be changed on a regular basis (plus the closed indicators); open and
+ * close times will only be changed at BDT Load time.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.4 ($Revision$), $Date$
+ */
+public class Market {
+	static class MarketImpl implements IMarket {
+
+		/**
+		 * Returns true if market is open for specified FIType
+		 * 
+		 * @return boolean
+		 */
+		String m_name;
+		String m_symbol;
+		String m_code = null; // this must be the Reuters code
+
+		String m_timeZone = null; // alpha TimeZone ID - can be used by
+									// TimeStamp methods)
+		String m_openTime = "09:30"; // default values //$NON-NLS-1$
+		String m_closeTime = "16:00"; //     same //$NON-NLS-1$
+		String m_countryCode = null;
+		String m_quoteCurrency = null;
+		Map<String, List<Time>> m_times = null; // HashMap of open and close times
+												// - key is fiType
+
+		Map<Date, Holiday> m_holidays = null; // list of holidays - keyed on date
+		Map<Date, Holiday> m_replHolidays = new HashMap<Date, Holiday>(); // used to build new holiday
+												// list
+		// TODO introdude ICU4J Holiday type and related framework
+		
+		/**
+		 * Returns true if market is open right now for specified FIType
+		 * 
+		 * @return boolean
+		 */
+
+		public boolean isOpen(String fiType) {
+
+			// TimeStamp ts = new TimeStamp(); // set timestamp to right now!
+			// return isOpen(ts, fiType);
+
+			return false;
+
+		}
+
+		/**
+		 * Returns true if market is open at specified time and for specified
+		 * FIType
+		 * 
+		 * @return boolean
+		 */
+
+		public boolean isOpen(Unit<Time> ts, String fiType) {
+
+			if (m_code.equals("M")) { //$NON-NLS-1$
+				System.err
+						.println("Montreal Exchange forced closed for testing!"); //$NON-NLS-1$
+				System.err.println("Remember to correct code later!"); //$NON-NLS-1$
+				return false;
+			}
+
+			String open = m_openTime;
+			String close = m_closeTime;
+			boolean closeInd = false;
+			if (m_times != null) {
+				List list = (List) m_times.get(fiType);
+				closeInd = list.get(0).equals("1"); //$NON-NLS-1$
+				open = (String) list.get(1);
+				close = (String) list.get(2);
+			}
+
+			if (closeInd)
+				return false;
+
+			// try {String nowInTZ = ts.formatWithZone(m_timeZone); // now in
+			// market time zone
+			//
+			// TimeZone tz = TimeTz.GetTimeZone(m_timeZone); // get from
+			// BDTHelper table
+			// String date = nowInTZ.substring(0,8);
+			//
+			// Calendar cal = new GregorianCalendar(tz); // needed to obtain day
+			// of week
+			// cal.setTime(ts);
+			// int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+			// HashMap hm = getHolidays();
+			// if (dayOfWeek == Calendar.SATURDAY || dayOfWeek ==
+			// Calendar.SUNDAY ||
+			// hm != null && null != hm.get(date)) // or is date in list of
+			// holidays?
+			// return false;
+			//
+			//
+			// TimeStamp tsStart = new TimeStamp(date + 'T' + open + '!' +
+			// m_timeZone);
+			// TimeStamp tsEnd = new TimeStamp(date + 'T' + close + '!' +
+			// m_timeZone);
+			//
+			// if (ts.before(tsStart) || ts.after(tsEnd))
+			// return false;
+			//
+			// }
+			// catch (BDTypeException ex) {
+			// System.err.println("Date error: " + ex);
+			// }
+			//
+			return true;
+
+		}
+
+		/**
+		 * Returns true if market is open for specified Date and FI Type
+		 * (partial dates will be treated as not open); times will not be
+		 * checked at all
+		 * 
+		 * @return boolean
+		 */
+		public boolean isOpen(Date date, String fiType) {
+
+			if (m_code.equals("M")) { //$NON-NLS-1$
+				System.err
+						.println("Montreal Exchange forced closed for testing!"); //$NON-NLS-1$
+				System.err.println("Remember to correct code later!"); //$NON-NLS-1$
+				return false;
+			}
+
+			boolean closeInd = false;
+			if (m_times != null) {
+				List list = (List) m_times.get(fiType);
+				closeInd = list.get(0).equals("1"); //$NON-NLS-1$
+			}
+
+			if (closeInd)
+				return false;
+
+			// try {TimeStamp timeWithinDate = new TimeStamp(date + "T12:00!" +
+			// m_timeZone);
+			//
+			// TimeZone tz = TimeTz.GetTimeZone(m_timeZone); // get from
+			// BDTHelper table
+			// Calendar cal = new GregorianCalendar(tz); // needed to obtain day
+			// of week
+			// cal.setTime(timeWithinDate);
+			// int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+			// HashMap hm = getHolidays();
+			// if (dayOfWeek == Calendar.SATURDAY || dayOfWeek ==
+			// Calendar.SUNDAY ||
+			// hm != null && null != hm.get(date)) // or is date in list of
+			// holidays?
+			// return false;
+			//
+			//
+			// }
+			// catch (BDTypeException ex) {
+			// System.err.println("Date error: " + ex);
+			// }
+
+			return true;
+
+		}
+
+		/**
+		 * Get HashMap of open/close times
+		 */
+
+		public Map<String, List<Time>> getTimes() {
+			return m_times;
+		}
+
+		/**
+		 * Set HashMap with open/close times
+		 */
+
+		public void setTimes(HashMap<String, List<Time>> hm) {
+			m_times = hm;
+		}
+
+		/**
+		 * Insert the method's description here. Creation date: (9/20/00 2:49:20
+		 * PM)
+		 * 
+		 * @return java.lang.String
+		 */
+		public String serialize() {
+
+			String str = m_code + ';' + m_timeZone + ';' + m_countryCode + ';'
+					+ m_quoteCurrency + ';' + '{';
+			Iterator iter = m_times.keySet().iterator();
+			boolean first = true;
+			while (iter.hasNext()) {
+				if (!first)
+					str = str + ';';
+				first = false;
+				String key = (String) iter.next();
+				List vec = (List) m_times.get(key);
+				str = str
+						+ key
+						+ "={" + vec.get(0) + ';' + vec.get(1) + ';' + vec.get(2) + '}'; //$NON-NLS-1$
+			}
+			str = str + "}{"; //$NON-NLS-1$
+
+			iter = m_holidays.keySet().iterator();
+			first = true;
+			while (iter.hasNext()) {
+				if (!first)
+					str = str + ';';
+				first = false;
+				Date d = (Date) iter.next();
+				str = str + d.toString();
+			}
+			str = str + '}';
+			return str;
+
+		}
+
+		MarketImpl(String s1, String s2, String s3, String s4) {
+			m_code = s1;
+			m_timeZone = s2;
+			m_countryCode = s3;
+			m_quoteCurrency = s4;
+		}
+
+		public String getTimeZone() {
+			return m_timeZone;
+		}
+
+		public synchronized Map<Date, Holiday> getHolidays() {
+			return m_holidays;
+		}
+
+		public synchronized void setHolidays(Map<Date, Holiday> hm) {
+			m_holidays = hm;
+		}
+
+		public Map<Date, Holiday> getReplHolidays() {
+			return m_replHolidays;
+		}
+
+		public void setReplHolidays(Map<Date, Holiday> hm) {
+			m_replHolidays = hm;
+		}
+
+		public void setTimes(Map<String, List<Time>> hm) {
+			m_times = hm;
+		}
+
+		public String getName() {
+			return m_name;
+		}
+
+		public String getSymbol() {
+			return m_symbol;
+		}
+
+	}
+
+	/**
+	 * Insert the method's description here. Creation date: (9/22/00 4:09:05 PM)
+	 * 
+	 * @return com.jpmorrsn.jbdtypes.IMarket
+	 * @param s1
+	 *            java.lang.String
+	 * @param s2
+	 *            java.lang.String
+	 * @param s3
+	 *            java.lang.String
+	 * @param s4
+	 *            java.lang.String
+	 */
+	static IMarket createMarket(String s1, String s2, String s3, String s4) {
+		return new MarketImpl(s1, s2, s3, s4);
+	}
+
+	/**
+	 * Return an IMarket object given the name - return null if string empty
+	 * 
+	 * @return org.eclipse.uomo.business.types.IMarket
+	 * @param s
+	 *            java.lang.String
+	 */
+	public static IMarket get(String s) throws BDTypeException {
+
+		if (s.equals("")) //$NON-NLS-1$
+			return null;
+		else {
+			IMarket mkt = BDTHelper.getMarkets().get(s);
+			if (mkt == null) {
+				// System.err.println("Invalid market code: " + s);
+				throw new BDTypeException(NLS.bind(
+						Messages.Market_invalid_code, s)); //$NON-NLS-1$
+			}
+			return mkt;
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/PercentAmount.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/PercentAmount.java
new file mode 100644
index 0000000..bfefee5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/PercentAmount.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types.impl;
+
+import static org.eclipse.uomo.business.types.BDTHelper.Operation.*;
+
+import org.eclipse.uomo.business.types.BDTHelper;
+import org.eclipse.uomo.business.types.IBasicType;
+import org.eclipse.uomo.business.types.Percent;
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.math.BigDecimal;
+
+/**
+ * This class describes Percent amounts
+ * @version 1.1
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public class PercentAmount extends BaseAmount<Percent> implements IBasicType, Percent {
+	final static long serialVersionUID = 362498820763181265L;
+
+	final static int precision = 15; // will be held, but not set
+
+	final BigDecimal percentValue;
+	
+	PercentAmount(char[] c, Unit<Percent> unit) {
+		super(new BigDecimal(c), unit);
+		percentValue = calcPercent(String.valueOf(c));
+	}
+
+	public PercentAmount(BigDecimal bd, Unit<Percent> unit) {
+		super(bd, unit);
+		percentValue = calcPercent(bd);
+	}
+
+	public PercentAmount(String s, Unit<Percent> unit) {
+		this(new BigDecimal(s), unit);
+	}
+
+	/**
+	 * Calculate a BigDecimal value for a Percent e.g. "3" (3 percent) will
+	 * generate an array containing .03
+	 * 
+	 * @return java.math.BigDecimal
+	 * @param s
+	 *            java.lang.String
+	 */
+	static BigDecimal calcPercent(BigDecimal b) {
+		BigDecimal temp = new BigDecimal("100"); //$NON-NLS-1$
+		return b.divide(temp, BDTHelper.MATH_CONTEXT); // we now have .03
+	}
+	
+	/**
+	 * Calculate a BigDecimal value for a Percent e.g. "3" (3 percent) will
+	 * generate an array containing .03
+	 * 
+	 * @return java.math.BigDecimal
+	 * @param s
+	 *            java.lang.String
+	 */
+	static BigDecimal calcPercent(String s) {
+		return calcPercent(new BigDecimal(s));
+	}
+
+	/**
+	 * Check if quantity is positive (>0)
+	 * 
+	 * @return boolean
+	 */
+	public boolean isPositive() {
+		return +1 == ((BigDecimal)getNumber()).compareTo(BigDecimal.ZERO);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is equal to
+	 * parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean eq(PercentAmount y) {
+		return BDTHelper.comp(this, y, EQ);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is greater than or
+	 * equal to parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean ge(PercentAmount y) {
+		return BDTHelper.comp(this, y, GE);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is greater than
+	 * parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean gt(PercentAmount y) {
+		return BDTHelper.comp(this, y, GT);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is less or equal to
+	 * parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean le(PercentAmount y) {
+		return BDTHelper.comp(this, y, LE);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is less than
+	 * parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean lt(PercentAmount y) {
+		return BDTHelper.comp(this, y, LT);
+	}
+
+	/**
+	 * Compare to see if <code> this </code> Percent amount is not equal to
+	 * parameter
+	 * 
+	 * @return boolean
+	 * @param y
+	 *            com.jpmorrsn.jbdtypes.Percent - second Percent
+	 */
+	public boolean ne(PercentAmount y) {
+		return BDTHelper.comp(this, y, NE);
+	}
+
+	/**
+	 * Generate a 'preference neutral' string from Percent value.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+		BigDecimal temp = (BigDecimal) getNumber();
+		temp = temp.multiply(BigDecimal.TEN, BDTHelper.MATH_CONTEXT);
+		temp = temp.multiply(BigDecimal.TEN, BDTHelper.MATH_CONTEXT);
+		temp = temp.divide(BigDecimal.ONE, BDTHelper.MATH_CONTEXT);
+		return temp.toString();
+
+	}
+
+	/**
+	 * Create a String from this object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return serialize();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/StockTicker.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/StockTicker.java
new file mode 100644
index 0000000..e9c02fe
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/StockTicker.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types.impl;
+
+import static org.eclipse.uomo.business.types.impl.DataHelper.BDT_DELIM;
+
+import org.eclipse.uomo.business.internal.Messages;
+import org.eclipse.uomo.business.types.BDTHelper;
+import org.eclipse.uomo.business.types.BDTypeException;
+import org.eclipse.uomo.business.types.IBDType;
+import org.eclipse.uomo.business.types.IMarket;
+import org.eclipse.uomo.core.ISymbol;
+
+/**
+ * Stock Ticker - composed of market, symbol and country codes - at least one of
+ * market and country will usually be present - if both are missing, we use the
+ * default country
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public class StockTicker implements IBDType, ISymbol {
+	IMarket m_market = null;
+	final String m_sym;
+	String m_country = ""; //$NON-NLS-1$
+
+	/**
+	 * Stock Ticker constructor using market;sym;country, where at least one of market
+	 * and country will usually be present - if both are missing, we use the
+	 * default country
+	 * 
+	 * @throws BDTypeException
+	 */
+	public StockTicker(String s) throws BDTypeException {
+		super();
+
+		int sp = s.indexOf(BDT_DELIM);
+		if (sp == -1)
+			throw new BDTypeException(Messages.StockTicker_invalid_symbol + s);
+		else {
+			String tmpMarket = s.substring(0, sp);
+			if (sp > 0) {
+				try {
+					m_market = Market.get(tmpMarket);
+				} // verify market is valid (added Oct. 3)
+				catch (BDTypeException e) {
+					throw new BDTypeException(Messages.StockTicker_invalid_market
+							+ s);
+				}
+			}
+
+			String s2 = s.substring(sp + 1);
+			sp = s2.indexOf(BDT_DELIM);
+			if (sp == -1)
+				m_sym = s2;
+			else {
+				m_sym = s2.substring(0, sp);
+				m_country = s2.substring(sp + 1);
+				if (!m_country.equals("") //$NON-NLS-1$
+						&& !(BDTHelper.getCountries().containsKey(m_country)))
+					throw new BDTypeException(
+							Messages.StockTicker_invalid_country + s);
+			}
+		}
+
+		if (m_sym.equals("")) //$NON-NLS-1$
+			throw new BDTypeException(Messages.StockTicker_missing_symbol
+					+ s);
+
+		if (m_market.equals("") && m_country.equals("")) //$NON-NLS-1$ //$NON-NLS-2$
+			m_country = BDTHelper.DEFAULT_COUNTRY;
+	}
+
+	/**
+	 * Get country String from object
+	 */
+	public String getCountry() {
+		return m_country;
+	}
+
+	/**
+	 * Get market String from object
+	 */
+	public IMarket getMarket() {
+		return m_market;
+	}
+
+	/**
+	 * Get symbol String from object
+	 */
+	public String getSymbol() {
+		return m_sym;
+	}
+
+	/**
+	 * Convert object to String
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+
+		String s1 = ""; //$NON-NLS-1$
+
+		if (m_market != null && !m_market.equals("")) //$NON-NLS-1$
+			s1 = m_market.getName();
+
+		s1 = s1 + BDT_DELIM + m_sym;
+
+		if (!m_country.equals("")) //$NON-NLS-1$
+			s1 = s1 + BDT_DELIM + m_country;
+
+		return s1;
+	}
+
+	/**
+	 * Create a String from this object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return serialize();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeStamp.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeStamp.java
new file mode 100644
index 0000000..7d0f887
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeStamp.java
@@ -0,0 +1,318 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.business.types.impl;
+
+import static org.eclipse.uomo.business.types.impl.DataHelper.BDT_DELIM;
+
+import java.text.SimpleDateFormat;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+import java.sql.Timestamp;
+
+import org.eclipse.uomo.business.types.IBasicType;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+
+/**
+ * Timestamp extends java.util.Date, which goes down to the millisecond
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public class TimeStamp extends java.util.Date implements IBasicType {
+	final static long serialVersionUID = 362498820763181265L;
+
+	/**
+	 * TimeStamp constructor - sets a TimeStamp to the current time
+	 */
+	public TimeStamp() {
+		super((TimeStamp.BuildTimeStamp()).getTime());
+
+	}
+
+	/**
+	 * TimeStamp constructor with millisecs (long)
+	 */
+	public TimeStamp(long m) {
+		super(m);
+
+	}
+
+	/**
+	 * TimeStamp constructor with String. buildTimeStamp returns a TimeStamp
+	 * object, which can't be used directly, so we use getTime
+	 * 
+	 * @throws UOMoRuntimeException
+	 */
+	public TimeStamp(String s) throws UOMoRuntimeException {
+		super((TimeStamp.BuildTimeStamp(s)).getTime());
+	}
+
+	/**
+	 * TimeStamp constructor with a java.sql.Timestamp buildTimeStamp returns a
+	 * TimeStamp object, which can't be used directly, so we use
+	 * getTime
+	 * 
+	 * @throws UOMoRuntimeException
+	 */
+	public TimeStamp(Timestamp ts) throws UOMoRuntimeException {
+		super((TimeStamp.BuildTimeStamp(ts)).getTime());
+	}
+
+	/**
+	 * Create a TimeStamp object using current time
+	 * 
+	 * @return TimeStamp
+	 */
+	static TimeStamp BuildTimeStamp() {
+
+		Calendar aGregCal = new GregorianCalendar();
+
+		java.util.Date date = aGregCal.getTime();
+		return new TimeStamp(date.getTime());
+	}
+
+	/**
+	 * Create an (non-Java.util) TimeStamp using a String. This has format
+	 * ccyymmddThh:mm:ssttt!zone;calendar;era where zone is an alpha time zone
+	 * name known to UOMo; calendar and era are optional. The time from :ss
+	 * is also optional. Instead of !zone, you may instead use Ahh:mm, where A
+	 * is + or -; in this case, no daylight savings time logic is available. If
+	 * adjustment and time zone are both missing, treat as 0, i.e. time is UTC
+	 * If an adjustment is present, the sign is as normally used to identify the
+	 * time zone - i.e. the offset needed to convert UTC to local time, even
+	 * though the first part is local time. This means that, to compute the UTC,
+	 * the sign must be reversed - i.e. local time 08:00 am in the EDT zone will
+	 * be represented as 08:00-04:00, so that UTC is computed by adding the two
+	 * values together. Calendar and era will be ignored for now.
+	 * 
+	 * @return TimeStamp
+	 * @param s
+	 *            java.lang.String
+	 * @throws UOMoRuntimeException
+	 */
+	static TimeStamp BuildTimeStamp(String s) throws UOMoRuntimeException {
+		String str;
+		int sp = s.indexOf(BDT_DELIM); // strip off calendar and/or era
+		if (sp == -1)
+			str = s;
+		else
+			str = s.substring(0, sp);
+
+		String adj = null;
+		TimeZone tz = null;
+
+		sp = str.indexOf('!');
+
+		if (sp > -1) {
+			String zoneString = str.substring(sp + 1);
+			tz = TimeTz.GetTimeZone(zoneString);
+			if (tz == null)
+				throw new UOMoRuntimeException("Time Zone not found: "
+						+ zoneString);
+			str = str.substring(0, sp);
+		}
+
+		else {
+			sp = str.indexOf('+');
+			if (sp == -1)
+				sp = str.indexOf('-');
+			if (sp > -1) {
+				adj = str.substring(sp);
+				str = str.substring(0, sp);
+			}
+		}
+
+		if (str.length() < 14)
+			throw new UOMoRuntimeException("Timestamp too short: " + s);
+
+		if (str.charAt(8) != 'T' || str.charAt(11) != ':')
+			throw new UOMoRuntimeException("Invalid TimeStamp: " + s);
+
+		String secs = "00000";
+
+		if (str.length() > 14) {
+			if (str.charAt(14) != ':')
+				throw new UOMoRuntimeException("Invalid TimeStamp: " + s);
+			if (str.length() != 17 && str.length() != 20)
+				throw new UOMoRuntimeException("Invalid TimeStamp: " + s);
+			secs = str.substring(15) + secs;
+			secs = secs.substring(0, 5);
+		}
+		TimeZone zone = TimeZone.getTimeZone("UTC");
+
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH:mmssSSS");
+		formatter.setTimeZone(zone);
+
+		String dateString = str.substring(0, 8) + str.substring(9, 14) + secs;
+
+		ParsePosition pos = new ParsePosition(0);
+		java.util.Date date = formatter.parse(dateString, pos);
+		TimeStamp ts = new TimeStamp(date.getTime());
+
+		long millis = 0;
+
+		if (tz != null) {
+			millis = ts.getTime();
+			millis -= tz.getRawOffset();
+			ts.setTime(millis);
+			if (tz.inDaylightTime(ts))
+				millis -= 3600000;
+			ts.setTime(millis);
+		}
+
+		if (adj != null) {
+			int hrs;
+			int mins = 0;
+
+			if (adj.length() == 3)
+				hrs = Integer.parseInt(adj.substring(1));
+			else {
+				if (adj.charAt(3) != ':' || adj.length() != 6)
+					throw new UOMoRuntimeException(
+							"Invalid TimeStamp adjustment: " + s);
+				hrs = Integer.parseInt(adj.substring(1, 3));
+				mins = Integer.parseInt(adj.substring(4, 6));
+			}
+
+			if (adj.charAt(0) == '+') {
+				hrs = -hrs;
+				mins = -mins;
+			} else if (adj.charAt(0) != '-')
+				throw new UOMoRuntimeException(
+						"Invalid TimeStamp adjustment sign: " + s);
+
+			millis = ts.getTime();
+
+			millis += (3600 * hrs + 60 * mins) * 1000;
+
+			ts.setTime(millis);
+		}
+
+		return ts;
+	}
+
+	/**
+	 * Create an TimeStamp using a java.sql.Timestamp. This differs
+	 * from an UOMo TimeStamp in that it goes down to the nanosecond. We
+	 * will therefore lose fractional milliseconds.
+	 * 
+	 * @return TimeStamp
+	 * @param ts
+	 *            java.sql.Timestamp
+	 * @throws UOMoRuntimeException
+	 */
+	static TimeStamp BuildTimeStamp(java.sql.Timestamp ts)
+			throws UOMoRuntimeException {
+		long millis = ts.getTime(); // gets integral number of seconds
+		millis += ts.getNanos() / 1000000;
+		return new TimeStamp(millis);
+	}
+
+	/**
+	 * Convert this TimeStamp to a java.sql.Timestamp
+	 * 
+	 * @return java.sql.Timestamp
+	 */
+	public Timestamp convertToSQL() {
+
+		long millis = getTime() % 1000;
+		java.sql.Timestamp ts = new Timestamp(this.getTime() - millis);
+		ts.setNanos((new Long(millis * 1000000)).intValue());
+		return ts;
+
+	}
+
+	/**
+	 * Format a (non-Java.util) TimeStamp object with specified alpha zone or
+	 * numeric (+/-) zone
+	 * 
+	 * @return java.lang.String
+	 * @throws UOMoRuntimeException
+	 */
+	public String formatWithZone(String s) throws UOMoRuntimeException {
+
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH:mm:ssSSS");
+		TimeZone zone = TimeZone.getTimeZone("UTC");
+
+		formatter.setTimeZone(zone);
+
+		long millis = getTime();
+
+		TimeStamp ts = new TimeStamp(millis);
+
+		String z = s;
+
+		if (s.charAt(0) == '+' || s.charAt(0) == '-') {
+			int hrs;
+			int mins = 0;
+
+			if (s.length() == 3)
+				hrs = Integer.parseInt(s.substring(1));
+			else {
+				if (s.charAt(3) != ':' || s.length() != 6)
+					throw new UOMoRuntimeException(
+							"Invalid TimeStamp adjustment: " + s);
+				hrs = Integer.parseInt(s.substring(1, 3));
+				mins = Integer.parseInt(s.substring(4, 6));
+			}
+
+			if (s.charAt(0) == '-') {
+				hrs = -hrs;
+				mins = -mins;
+			}
+			millis += (hrs * 3600 + mins * 60) * 1000;
+			ts.setTime(millis);
+		} else {
+			TimeZone tz = TimeTz.GetTimeZone(s);
+			if (tz == null)
+				throw new UOMoRuntimeException("Time Zone not found: " + s);
+			millis += tz.getRawOffset();
+			ts.setTime(millis);
+			if (tz.inDaylightTime(ts))
+				ts.setTime(millis + 3600000);
+			z = '!' + s;
+		}
+
+		String str = formatter.format(ts);
+		str = str.substring(0, 8) + 'T' + str.substring(8) + z;
+
+		return str;
+
+	}
+
+	/**
+	 * Display a (non-Java.util) TimeStamp object as a 26-byte string
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH:mm:ssSSS");
+		TimeZone zone = TimeZone.getTimeZone("UTC");
+
+		formatter.setTimeZone(zone);
+
+		String str = formatter.format(this);
+		str = str.substring(0, 8) + 'T' + str.substring(8) + "+00:00";
+		return str;
+
+	}
+
+	/**
+	 * Create a String from this object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return serialize();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeTz.java b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeTz.java
new file mode 100644
index 0000000..c5fd41d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/java/org/eclipse/uomo/business/types/impl/TimeTz.java
@@ -0,0 +1,68 @@
+package org.eclipse.uomo.business.types.impl;
+
+import java.util.TimeZone;
+
+import org.eclipse.uomo.business.types.IBasicType;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+
+/**
+ * TimeTz is mostly needed in conjunction with dates, so it is held as a String
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+class TimeTz implements IBasicType {
+	String m_ttz;
+
+	/**
+	 * TimeTz constructor with String. Format is same as time and adjustment
+	 * part of TimeStamp string.
+	 */
+	public TimeTz(String s) {
+		m_ttz = s;
+	}
+
+	/**
+	 * Build a TimeStamp using specified Date object
+	 * 
+	 * @return com.jpmorrsn.jbdtypes.TimeStamp
+	 * @param d
+	 *            com.jpmorrsn.jbdtypes.Date
+	 * @throws BDTypeException
+	 */
+	TimeStamp buildTimeStamp(BDate d) throws UOMoRuntimeException {
+
+		return new TimeStamp(d.serialize() + 'T' + m_ttz);
+
+	}
+
+	/**
+	 * Find a TimeZone (alpha only) in static TimeZone table
+	 * 
+	 * @return java.util.SimpleTimeZone
+	 * @param s
+	 *            java.lang.String
+	 */
+	public static TimeZone GetTimeZone(String s) {
+		return (TimeZone) DataHelper.s_timeZoneTable.get(s);
+	}
+
+	/**
+	 * Display a TimeTz object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String serialize() {
+
+		return m_ttz;
+
+	}
+
+	/**
+	 * Create a String from this object
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return serialize();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages.properties b/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages.properties
new file mode 100644
index 0000000..755ebfc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages.properties
@@ -0,0 +1,7 @@
+CurrencyConverter_exchangeRate_not_set=Exchange rate from {} to {} not set.
+CurrencyConverter_toString=%s - %s
+Market_invalid_code=Invalid market code: {} 
+StockTicker_invalid_symbol=Invalid symbol string: 
+StockTicker_invalid_market=Invalid market code in ticker: 
+StockTicker_invalid_country=Invalid country code in ticker: 
+StockTicker_missing_symbol=Missing symbol within Ticker string: 
diff --git a/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages_de.properties b/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages_de.properties
new file mode 100644
index 0000000..12f13dc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.business/src/main/resources/org/eclipse/uomo/business/internal/messages_de.properties
@@ -0,0 +1,5 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+
+CurrencyConverter_exchangeRate_not_set = Wechselkurs von {} nach {} nicht gesetzt.
+
+Market_invalid_code = Ung\u00FCltiger Marktcode: {} 
diff --git a/bundles/org.eclipse.uomo.core.tests/.classpath b/bundles/org.eclipse.uomo.core.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.core.tests/.gitignore b/bundles/org.eclipse.uomo.core.tests/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.core.tests/.project b/bundles/org.eclipse.uomo.core.tests/.project
new file mode 100644
index 0000000..1bb8f37
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.core.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.core.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.core.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..79f381e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.core.tests
+Bundle-SymbolicName: org.eclipse.uomo.core.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.core;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.uomo.core.impl;
+  uses:="org.eclipse.uomo.core"
+Require-Bundle: org.junit
diff --git a/bundles/org.eclipse.uomo.core.tests/build.properties b/bundles/org.eclipse.uomo.core.tests/build.properties
new file mode 100644
index 0000000..ced5f40
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.core.tests/pom.xml b/bundles/org.eclipse.uomo.core.tests/pom.xml
new file mode 100644
index 0000000..0d4e688
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.core.tests</artifactId>
+	<name>UOMo Core Tests</name>
+	<packaging>eclipse-test-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core.tests/src/log4j.properties b/bundles/org.eclipse.uomo.core.tests/src/log4j.properties
new file mode 100644
index 0000000..18cfaa3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/src/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootCategory=INFO, stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout.ConversionPattern=%t %p [%c] - %m%n
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.threshold=TRACE
+
+#log4j.logger.org.springframework.osgi=DEBUG
+#log4j.logger.org.springframework=DEBUG
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core.tests/src/org/eclipse/uomo/core/impl/BeanImplTest.java b/bundles/org.eclipse.uomo.core.tests/src/org/eclipse/uomo/core/impl/BeanImplTest.java
new file mode 100644
index 0000000..816e745
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core.tests/src/org/eclipse/uomo/core/impl/BeanImplTest.java
@@ -0,0 +1,15 @@
+package org.eclipse.uomo.core.impl;
+
+import junit.framework.TestCase;
+
+import org.eclipse.uomo.core.IBean;
+import org.eclipse.uomo.core.impl.Bean;
+
+public class BeanImplTest extends TestCase {
+
+    public void testBeanIsABean() {
+	IBean aBean = new Bean();
+        assertTrue(aBean.isABean());
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/.classpath b/bundles/org.eclipse.uomo.core/.classpath
new file mode 100644
index 0000000..47ca448
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="src" path="src/main/resources/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.core/.gitignore b/bundles/org.eclipse.uomo.core/.gitignore
new file mode 100644
index 0000000..df81231
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/.gitignore
@@ -0,0 +1,3 @@
+/target
+/eclipse_config
+/.settings
diff --git a/bundles/org.eclipse.uomo.core/.project b/bundles/org.eclipse.uomo.core/.project
new file mode 100644
index 0000000..727de68
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/.project
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.jboss.tools.jst.web.kb.kbbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.jboss.tools.jst.web.kb.kbnature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.core/.springBeans b/bundles/org.eclipse.uomo.core/.springBeans
new file mode 100644
index 0000000..6c6cb5a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.5.0.201010221000-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8c6d4c4
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Export-Package: org.eclipse.uomo.core,
+ org.eclipse.uomo.core.impl
+Private-Package: org.eclipse.uomo.core;version=0.2.0.SNAPSHOT,
+ org.eclipse.uomo.core.impl;version=0.2.0.SNAPSHOT
+Bundle-ActivationPolicy: lazy
+Tool: Bnd-0.0.160
+Bundle-Name: org.eclipse.uomo.core
+Created-By: 1.6.0_23-ea(SunMicrosystemsInc.)
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.osgi.services;bundle-version="3.2.100";visibility:=reexport,
+ org.eclipse.core.runtime;bundle-version="3.10.0",
+ org.unitsofmeasurement.unit-api;bundle-version="0.6.1"
+Bundle-Vendor: Eclipse OSBP
+Bundle-Version: 0.6.0.qualifier
+Bnd-LastModified: 1288905964975
+Bundle-Activator: org.eclipse.uomo.core.internal.Activator
+Bundle-ManifestVersion: 2
+Bundle-Description: UOMoaddsUnitsofMeasurementsupportforITSystemsandServicesbothtoLanguageandData.
+Import-Package: org.osgi.framework;version="1.3",
+ org.osgi.util.tracker
+Bundle-SymbolicName: org.eclipse.uomo.core
+Bundle-DocURL: http://www.eclipse.org
+Include-Resource: src/main/resources
+Originally-Created-By: 1.6.0_23-ea(SunMicrosystemsInc.)
+Bundle-ClassPath: org.eclipse.uomo.core/libs/icu4j-50_1_1.jar,.
+
+
diff --git a/bundles/org.eclipse.uomo.core/build.properties b/bundles/org.eclipse.uomo.core/build.properties
new file mode 100644
index 0000000..c0f224d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/build.properties
@@ -0,0 +1,5 @@
+source.. = src/main/java/,src/main/resources/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .,\
+               libs/icu4j-50_1_1.jar
diff --git a/bundles/org.eclipse.uomo.core/libs/README b/bundles/org.eclipse.uomo.core/libs/README
new file mode 100644
index 0000000..9edcad5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/libs/README
@@ -0,0 +1,3 @@
+This jar file is included here because it cannot be downloaded from a public p2 repository at this time.
+
+If this file is included in Orbit - it can be removed.
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/libs/icu4j-50_1_1.jar b/bundles/org.eclipse.uomo.core/libs/icu4j-50_1_1.jar
new file mode 100644
index 0000000..4994a5c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/libs/icu4j-50_1_1.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.core/pom.xml b/bundles/org.eclipse.uomo.core/pom.xml
new file mode 100644
index 0000000..b7b3aae
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/pom.xml
@@ -0,0 +1,28 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>org.eclipse.uomo.bundles</artifactId>
+        <groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        <version>0.6.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <artifactId>org.eclipse.uomo.core</artifactId>
+    <name>UOMo Core</name>
+    <packaging>eclipse-plugin</packaging>
+    <properties>
+        <site.basedir>${project.parent.basedir}</site.basedir>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.core</groupId>
+            <artifactId>runtime</artifactId>
+            <version>3.10.0-v20140318-2214</version>
+        </dependency>
+		<dependency>
+            <groupId>org.unitsofmeasurement</groupId>
+            <artifactId>unit-api</artifactId>
+            <version>0.6.1</version>
+		</dependency>
+    </dependencies>
+</project>
diff --git a/bundles/org.eclipse.uomo.core/readme.txt b/bundles/org.eclipse.uomo.core/readme.txt
new file mode 100644
index 0000000..b81ea35
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/readme.txt
@@ -0,0 +1,2 @@
+To facilitate OSGi bundle manifest generation, the archetype uses Felix maven plugin.
+Please see http://felix.apache.org/site/maven-bundle-plugin-bnd.html for more information.
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IBean.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IBean.java
new file mode 100644
index 0000000..fa6a020
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IBean.java
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * A bean.
+ *
+ * @version $Id$
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @deprecated For integration only
+ */
+public interface IBean {
+
+    boolean isABean();
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ICode.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ICode.java
new file mode 100644
index 0000000..0fc770a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ICode.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a code.
+ *
+ * @version $Id: ICode.java 63 2010-07-19 10:35:31Z werner.keil $
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface ICode {
+	String getCode();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IDescription.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IDescription.java
new file mode 100644
index 0000000..72df53e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IDescription.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a description.
+ *
+ * @version $Id: IIDescription.java 63 2010-07-19 10:35:31Z werner.keil $
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IDescription {
+	String getDescription();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IListValidator.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IListValidator.java
new file mode 100644
index 0000000..78d5e00
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IListValidator.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Unit-API and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.core;
+
+import java.util.List;
+
+/**
+ * @author  <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ * 
+ * @param <V> the validated type
+ *
+ */
+public interface IListValidator<V> {
+    public List<V> validate();
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IName.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IName.java
new file mode 100644
index 0000000..5c6cc0a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IName.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a name. This is true for units and similar entities.
+ * 
+ * @version $Id: IName.java 152 2010-08-22 20:48:31Z werner.keil $
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IName {
+	String getName();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INames.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INames.java
new file mode 100644
index 0000000..0f39ba1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INames.java
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2005, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+import java.util.List;
+
+/**
+ * Denote entity that has a list of names.
+ * 
+ * @version $Id: IName.java 152 2010-08-22 20:48:31Z werner.keil $
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface INames {
+	List<String> getNames();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INumericValue.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INumericValue.java
new file mode 100644
index 0000000..bcbac66
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/INumericValue.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2011, 2013 Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a numeric value.
+ *
+ * @version 0.2
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface INumericValue {
+	Number getValue();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ISymbol.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ISymbol.java
new file mode 100644
index 0000000..c52713e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/ISymbol.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a symbol. 
+ * This is true for units and similar entities.
+ * 
+ * @version $Id: INameAndSymbol.java 94 2010-07-30 18:36:25Z werner.keil $
+ * @author <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ */
+public interface ISymbol {
+	String getSymbol();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IText.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IText.java
new file mode 100644
index 0000000..0ff116a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IText.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2011, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a text value.
+ *
+ * @version 0.1
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IText {
+	String getText();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IValidator.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IValidator.java
new file mode 100644
index 0000000..90d5729
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IValidator.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API
+ */
+package org.eclipse.uomo.core;
+
+/**
+ * @author <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ * 
+ * @param <V>
+ *            the type to validate
+ * 
+ */
+public interface IValidator<V> {
+	public void validate(V v) throws UOMoException;
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVersion.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVersion.java
new file mode 100644
index 0000000..e7b7ca3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVersion.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 1997, 2013, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a version number.
+ *
+ * @version 0.2
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IVersion {
+	String getVersion();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVisibleName.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVisibleName.java
new file mode 100644
index 0000000..4467b76
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/IVisibleName.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2011, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * Denote entity that has a visible name.
+ * 
+ * @version $Id: IName.java 152 2010-08-22 20:48:31Z werner.keil $
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public interface IVisibleName {
+	String visibleName();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoError.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoError.java
new file mode 100644
index 0000000..2f98e9a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoError.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Copyright (c) 2010-2013 Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * @author  <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ * @version 1.1, $Date: 2013-05-12 $
+ * @deprecated this may not be used, consider removing it before 1.0
+ */
+public class UOMoError extends Error {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 4314692361098674055L;
+
+	/**
+	 * Constructs from an error message.
+	 * 
+	 * @param message
+	 *            The error message.
+	 */
+	public UOMoError(final String message) {
+		super(message);
+	}	
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoException.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoException.java
new file mode 100644
index 0000000..a1ebaf7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoException.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2010, Copyright (c) 2010 Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * @author  <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2010-09-11 17:42:22 +0200 (Sa, 11 Sep 2010) $
+ */
+public class UOMoException extends Exception {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5878541642974988679L;
+
+	/**
+	 * Constructs from an error message.
+	 * 
+	 * @param message
+	 *            The error message.
+	 */
+	public UOMoException(final String message) {
+		super(message);
+	}
+	
+	public UOMoException(String message, Throwable causingException) {
+		super(message, causingException);
+	}
+
+	public UOMoException(Throwable causingException) {
+		super(causingException);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoRuntimeException.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoRuntimeException.java
new file mode 100644
index 0000000..94978f1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/UOMoRuntimeException.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2010, Copyright (c) 2010 Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.core;
+
+/**
+ * @author  <a href="mailto:oumo@catmedia.us">Werner Keil</a>
+ * @version 1.1, $Date: 2010-07-19 11:35:31 +0100 (Mo, 19 Jul 2010) $
+ */
+public class UOMoRuntimeException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5878541642974988679L;
+
+	/**
+	 * Constructs from an error message.
+	 * 
+	 * @param message
+	 *            The error message.
+	 */
+	public UOMoRuntimeException(final String message) {
+		super(message);
+	}
+	
+	public UOMoRuntimeException(String message, Throwable causingException) {
+		super(message, causingException);
+	}
+
+	public UOMoRuntimeException(Throwable causingException) {
+		super(causingException);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Bean.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Bean.java
new file mode 100644
index 0000000..0b124fe
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Bean.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 1996, 2010, Werner Keil, Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *****************************************************************************/
+
+package org.eclipse.uomo.core.impl;
+
+import org.eclipse.uomo.core.IBean;
+
+public class Bean implements IBean {
+
+    public boolean isABean() {
+	return true;
+    }
+
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/LogServiceImpl.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/LogServiceImpl.java
new file mode 100644
index 0000000..290a23b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/LogServiceImpl.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.core.impl;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+public class LogServiceImpl implements LogService {
+
+	public void log(int arg0, String arg1) {
+		OutputHelper.print(arg1);
+	}
+
+	public void log(int arg0, String arg1, Throwable arg2) {
+		OutputHelper.print(arg1 + " " + arg2);
+	}
+
+	public void log(ServiceReference arg0, int arg1, String arg2) {
+		OutputHelper.print(arg2);
+	}
+
+	public void log(ServiceReference arg0, int arg1, String arg2, Throwable arg3) {
+		log(arg1, arg2, arg3);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/OutputHelper.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/OutputHelper.java
new file mode 100644
index 0000000..606d26c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/OutputHelper.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.core.impl;
+
+/**
+ * A static helper class, checking e.g. if some tests require optional console
+ * output XXX this could have options for using a logging framework eventually
+ * TODO change to Service (either OSGi LogService or separate service)
+ * @version $Revision: 97 $, $Date: 2010-07-30 20:13:27 +0100 (Fr, 30 Jul 2010) $
+ * @author Werner Keil
+ */
+public abstract class OutputHelper {
+	public static final String CONSOLE_OUTPUT = "consoleOutput";
+
+	public static final boolean isConsoleOutput() {
+		return ("true".equals(System.getProperty(CONSOLE_OUTPUT)));
+	}
+
+	public static final void print(String message) {
+		if (isConsoleOutput()) {
+			System.out.print(message);
+		}
+	}
+
+	public static final void println(String message) {
+		if (isConsoleOutput()) {
+			System.out.println(message);
+		}
+	}
+
+	public static final void print(Object object) {
+		print(String.valueOf(object));
+	}
+
+	public static final void println(Object object) {
+		println(String.valueOf(object));
+	}
+
+	/**
+	 * This is a Fantom-style convenience method for console output
+	 */
+	public static final void echo(Object obj) {
+		println(obj);
+	}
+
+	/**
+	 * This is a Fantom-style convenience method for console output
+	 */
+	public static final void echo(String str) {
+		println(str);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Pair.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Pair.java
new file mode 100644
index 0000000..0d333d5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/impl/Pair.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2013, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.core.impl;
+
+/**
+ * @author Werner Keil
+ *
+ * @param <V>
+ * @param <C>
+ */
+public class Pair<V, C> {
+
+	private V value;
+	private C code;
+	/**
+	 * @param value
+	 * @param code
+	 */
+	public Pair(V value, C code) {
+		super();
+		this.value = value;
+		this.code = code;
+	}
+	/**
+	 * @return the value
+	 */
+	public V getValue() {
+		return value;
+	}
+	/**
+	 * @return the code
+	 */
+	public C getCode() {
+		return code;
+	}	
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Activator.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Activator.java
new file mode 100644
index 0000000..4ff473f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Activator.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2010, 2012 Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.core.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * OSGi part of implementation.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.3 ($Revision$), $Date$
+ */
+public class Activator implements BundleActivator {
+	private BundleContext fContext;
+	
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void start(BundleContext context) throws Exception {
+		fContext = context;
+	}
+
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		// close the service tracker(s)
+		// stopDictionary();
+		fContext = null;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Messages.java b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Messages.java
new file mode 100644
index 0000000..6a04c02
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/java/org/eclipse/uomo/core/internal/Messages.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2010, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.core.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public final class Messages {
+	private static final String BUNDLE_NAME = "org.eclipse.uomo.core.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private Messages() {
+	}
+
+	static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context-osgi.xml b/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context-osgi.xml
new file mode 100644
index 0000000..95ee05d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context-osgi.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns:osgi="http://www.springframework.org/schema/osgi"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+  <!-- definitions using elements of the osgi namespace can be included
+       in this file. There is no requirement to keep these definitions
+       in a separate file if you do not want to. The rationale for 
+       keeping these definitions separate is to facilitate integration
+       testing of the bundle outside of an OSGi container -->
+
+</beans>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context.xml b/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context.xml
new file mode 100644
index 0000000..2459eb0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/resources/META-INF/spring/bundle-context.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+  <!-- regular spring configuration file defining the beans for this
+       bundle. We've kept the osgi definitions in a separate 
+       configuration file so that this file can easily be used
+       for integration testing outside of an OSGi environment -->
+
+  <bean name="myBean" class="org.eclipse.uomo.core.impl.BeanImpl" />
+
+</beans>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/resources/log4j.properties b/bundles/org.eclipse.uomo.core/src/main/resources/log4j.properties
new file mode 100644
index 0000000..18cfaa3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootCategory=INFO, stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout.ConversionPattern=%t %p [%c] - %m%n
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.threshold=TRACE
+
+#log4j.logger.org.springframework.osgi=DEBUG
+#log4j.logger.org.springframework=DEBUG
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.core/src/main/resources/org/eclipse/uomo/core/internal/messages.properties b/bundles/org.eclipse.uomo.core/src/main/resources/org/eclipse/uomo/core/internal/messages.properties
new file mode 100644
index 0000000..ad4f43c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.core/src/main/resources/org/eclipse/uomo/core/internal/messages.properties
@@ -0,0 +1,8 @@
+
+UOMoNumberFormatException.INTERNAL_ERROR = INTERNAL ERROR
+UOMoNumberFormatException.NINF           = NINF
+UOMoNumberFormatException.NaN            = NaN
+UOMoNumberFormatException.PINF           = PINF
+UOMoNumberFormatException.RULE           = RULE
+UOMoNumberFormatException.SIZE           = SIZE
+UOMoNumberFormatException.TEXT_FORMAT     = text format
diff --git a/bundles/org.eclipse.uomo.ucum.tests/.classpath b/bundles/org.eclipse.uomo.ucum.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.ucum.tests/.gitignore b/bundles/org.eclipse.uomo.ucum.tests/.gitignore
new file mode 100644
index 0000000..4dc0091
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/bundles/org.eclipse.uomo.ucum.tests/.project b/bundles/org.eclipse.uomo.ucum.tests/.project
new file mode 100644
index 0000000..aac1ce5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.ucum.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.ucum.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.ucum.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bffe32c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.ucum.tests
+Bundle-SymbolicName: org.eclipse.uomo.ucum.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.ucum;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.uomo.ucum.tests
+Require-Bundle: org.junit;bundle-version="4.8.2",
+ org.eclipse.uomo.util;bundle-version="0.6.0",
+ org.eclipse.uomo.xml;bundle-version="0.6.0",
+ org.xmlpull;bundle-version="1.1.3"
+
diff --git a/bundles/org.eclipse.uomo.ucum.tests/build.properties b/bundles/org.eclipse.uomo.ucum.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.ucum.tests/pom.xml b/bundles/org.eclipse.uomo.ucum.tests/pom.xml
new file mode 100644
index 0000000..faee3bb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/pom.xml
@@ -0,0 +1,14 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.ucum.tests</artifactId>
+	<name>UOMo UCUM Tests</name>
+	<packaging>eclipse-test-plugin</packaging>
+
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/UcumFunctionalTests.xml b/bundles/org.eclipse.uomo.ucum.tests/src/UcumFunctionalTests.xml
new file mode 100644
index 0000000..09c534c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/UcumFunctionalTests.xml
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>  
+<ucumTests>
+<!--
+  Ucum Functional Tests. 
+  
+  This file is maintained by Grahame Grieve (grahameg@gmail.com).
+  Contributions/Corrections are welcome, and are best made through
+  the trac system at unitsofmeasure.org
+  
+  Conformance:
+    You may declare conformance to these UCUM functional tests if 
+	your implementation accepts this file as an input, and passes 
+	all the test cases below. You should always quote the most 
+	recent date from the history entries below when claiming 
+	conformance.
+	
+	You may qualify the conformance to particular kinds of cases if your
+	functionality does not cover all the tests.
+	
+	Note that conformance to these tests does not equate to 
+	conformance to UCUM itself - though one could reasonably 
+	claim to be compliant with UCUM if one is conformant to these
+	tests.
+
+  This file is copyright © 2008 - 2009 Grahame Grieve and other 
+  contributers:
+    * Gunther Schadow
+	* Lloyd Mackenzie
+ 
+  This source is licensed for public use under the Eclipse Public License 
+  (http://www.eclipse.org/legal/epl-v10.html). 
+  
+-->
+  <history>
+     <entry date="10-Feb 2009" author="gdg">First created. Ucum validation Tests, display name generation tests, conversion tests, and multiplication tests</entry>
+  </history>
+  <!-- Note: all tests use case sensitive codes -->
+  <validation>
+    <!-- 
+	  These tests check that ucum validation code is working correctly. 
+	  Each case has a unit, and whether the specified unit is valid or not
+	  No particular error is specified, but a hint is provided for why the 
+	  unit is not valid
+	 -->
+    <case id="1-101" unit="m" valid="true"/>
+	<case id="1-102" unit="m/" valid="false" reason="/ is not followed by a term"/>
+	<case id="1-103" unit="" valid="true"/>
+	<case id="1-104" unit="/m" valid="true"/>
+	<case id="1-105" unit="10*3/ul" valid="true"/>
+	<case id="1-106" unit="10*-3/ul" valid="true"/>
+	<case id="1-107" unit="10*+3/ul" valid="true"/>
+	<case id="1-108" unit="10+3/ul" valid="false" reason="10 is not a valid unit"/>
+	<case id="1-109" unit="m" valid="true"/>
+	<case id="1-110" unit="m[H2O]" valid="true"/>
+	<case id="1-111" unit="10*23" valid="true"/>
+	<case id="1-112" unit="rad2" valid="true"/>
+	<case id="1-113" unit="m3.kg-1.s-2" valid="true"/>
+	<case id="1-114" unit="4.[pi].10*-7.N/A2" valid="true"/>
+	<!-- test that the parser supports both {} inserts, and unicode characters too, while we're at it -->
+	<case id="1-115" unit="rad2{錠}" valid="true"/>
+	<case id="1-116" unit="{錠}rad2{錠}" valid="true"/>		
+	<case id="1-117" unit="1{錠}" valid="true"/>
+	<case id="1-118" unit="{錠}1" valid="true"/>
+	<case id="1-119" unit="{錠}" valid="true"/>
+	<case id="1-120" unit="%" valid="true"/>
+	
+	<!-- 
+	  These codes are taken from the first draft of a proposed Canadian UCUM subset. 
+	  (the subset was subsequently corrected after being tested) -->
+	  
+	<case id="1-121" unit="[cup_us]" valid="true"/>
+	<case id="1-122" unit="[foz_br]" valid="true"/>
+	<case id="1-123" unit="[ft_i]" valid="true"/>
+	<case id="1-124" unit="[in_i]" valid="true"/>
+	<case id="1-125" unit="[yd_i]" valid="true"/>
+	<case id="1-126" unit="[gal_br]" valid="true"/>
+	<case id="1-127" unit="[lb_av]" valid="true"/>
+	<case id="1-128" unit="[oz_av]" valid="true"/>
+	<case id="1-129" unit="[pt_br]" valid="true"/>
+	<case id="1-130" unit="[qt_br]" valid="true"/>
+	<case id="1-131" unit="[sft_i]" valid="true"/>
+	<case id="1-132" unit="[sin_i]" valid="true"/>
+	<case id="1-133" unit="[syd_i]" valid="true"/>
+	<case id="1-134" unit="[tbs_us]" valid="true"/>
+	<case id="1-135" unit="[tsp_us]" valid="true"/>
+	<case id="1-136" unit="1/d" valid="true"/>
+	<case id="1-137" unit="1/min" valid="true"/>
+	<case id="1-138" unit="a" valid="true"/>
+	<case id="1-139" unit="cm" valid="true"/>
+	<case id="1-140" unit="cm2" valid="true"/>
+	<case id="1-141" unit="cm3" valid="true"/>
+	<case id="1-142" unit="d" valid="true"/>
+	<case id="1-143" unit="dg" valid="true"/>
+	<case id="1-144" unit="dl" valid="true"/>
+	<case id="1-145" unit="g" valid="true"/>
+	<case id="1-146" unit="g/d" valid="true"/>
+	<case id="1-147" unit="g/l" valid="true"/>
+	<case id="1-148" unit="h" valid="true"/>
+	<case id="1-149" unit="iU" valid="false" reason="iU needs [] around it"/>
+	<case id="1-150" unit="kg" valid="true"/>
+	<case id="1-151" unit="l" valid="true"/>
+	<case id="1-152" unit="m" valid="true"/>
+	<case id="1-153" unit="mm" valid="true"/>
+	<case id="1-154" unit="m2" valid="true"/>
+	<case id="1-155" unit="meq" valid="true"/>
+	<case id="1-156" unit="mg" valid="true"/>
+	<case id="1-157" unit="mg" valid="true"/>
+	<case id="1-158" unit="mg/d" valid="true"/>
+	<case id="1-159" unit="min" valid="true"/>
+	<case id="1-160" unit="ml" valid="true"/>
+	<case id="1-161" unit="ml/s" valid="true"/>
+	<case id="1-162" unit="mm[Hg]" valid="true"/>
+	<case id="1-163" unit="mm2" valid="true"/>
+	<case id="1-164" unit="mm3" valid="true"/>
+	<case id="1-165" unit="mmol" valid="true"/>
+	<case id="1-166" unit="mmol/l" valid="true"/>
+	<case id="1-167" unit="mo" valid="true"/>
+	<case id="1-168" unit="mol" valid="true"/>
+	<case id="1-169" unit="ms" valid="true"/>
+	<case id="1-170" unit="mU" valid="true"/>
+	<case id="1-171" unit="ng" valid="true"/>
+	<case id="1-172" unit="ng" valid="true"/>
+	<case id="1-173" unit="nl" valid="true"/>
+	<case id="1-174" unit="nl" valid="true"/>
+	<case id="1-175" unit="pg/ml" valid="true"/>
+	<case id="1-176" unit="s" valid="true"/>
+	<case id="1-177" unit="U" valid="true"/>
+	<case id="1-178" unit="U/l" valid="true"/>
+	<case id="1-179" unit="ug" valid="true"/>
+	<case id="1-180" unit="ug/min" valid="true"/>
+	<case id="1-181" unit="ul" valid="true"/>
+	<case id="1-182" unit="umol" valid="true"/>
+	<case id="1-183" unit="umol/l" valid="true"/>
+	<case id="1-184" unit="wk" valid="true"/>
+	<case id="1-185" unit="%" valid="true"/>
+	<case id="1-186" unit="[cup_us]" valid="true"/>
+	<case id="1-187" unit="[foz_br]" valid="true"/>
+	<case id="1-188" unit="[gal_br]" valid="true"/>
+	<case id="1-189" unit="[sft_i]" valid="true"/>
+	<case id="1-190" unit="[sin_i]" valid="true"/>
+	<case id="1-191" unit="[lb_av]" valid="true"/>
+	<case id="1-192" unit="[oz_av]" valid="true"/>
+	<case id="1-193" unit="[pt_br]" valid="true"/>
+	<case id="1-194" unit="[qt_br]" valid="true"/>
+	<case id="1-195" unit="[tbs_us]" valid="true"/>
+	<case id="1-196" unit="[tsp_us]" valid="true"/>
+	<case id="1-197" unit="[syd_i]" valid="true"/>
+	<case id="1-198" unit="cm2" valid="true"/>
+	<case id="1-199" unit="cm3" valid="true"/>
+	<case id="1-200" unit="g" valid="true"/>
+	<case id="1-201" unit="kg" valid="true"/>
+	<case id="1-202" unit="l" valid="true"/>
+	<case id="1-203" unit="m2" valid="true"/>
+	<case id="1-204" unit="meq" valid="true"/>
+	<case id="1-205" unit="mg" valid="true"/>
+	<case id="1-206" unit="ml" valid="true"/>
+	<case id="1-207" unit="mm2" valid="true"/>
+	<case id="1-208" unit="mm3" valid="true"/>
+	<case id="1-209" unit="mmol" valid="true"/>
+	<case id="1-210" unit="molv" valid="false" reason="molv is not a valid unit"/>
+	<case id="1-211" unit="mU" valid="true"/>
+	<case id="1-212" unit="ng" valid="true"/>
+	<case id="1-213" unit="nl" valid="true"/>
+	<case id="1-214" unit="U" valid="true"/>
+	<case id="1-215" unit="ug" valid="true"/>
+	<case id="1-216" unit="ul" valid="true"/>
+	<case id="1-217" unit="umol" valid="true"/>
+	<case id="1-218" unit="a" valid="true"/>
+	<case id="1-219" unit="d" valid="true"/>
+	<case id="1-220" unit="h" valid="true"/>
+	<case id="1-221" unit="min" valid="true"/>
+	<case id="1-222" unit="mo" valid="true"/>
+	<case id="1-223" unit="s" valid="true"/>
+	<case id="1-224" unit="wk" valid="true"/>
+	<case id="1-225" unit="[ft_i]" valid="true"/>
+	<case id="1-226" unit="[in_i]" valid="true"/>
+	<case id="1-227" unit="[lb_av]" valid="true"/>
+	<case id="1-228" unit="[oz_av]" valid="true"/>
+	<case id="1-229" unit="[yd_i]" valid="true"/>
+	<case id="1-230" unit="cm" valid="true"/>
+	<case id="1-231" unit="g" valid="true"/>
+	<case id="1-232" unit="kg" valid="true"/>
+	<case id="1-233" unit="m" valid="true"/>
+	<case id="1-234" unit="mm" valid="true"/>
+	<case id="1-235" unit="[mi_us]" valid="true"/>
+	<case id="1-236" unit="[yd_i]" valid="true"/>
+	<case id="1-237" unit="deg" valid="true"/>
+	<case id="1-238" unit="km" valid="true"/>
+	<case id="1-239" unit="m" valid="true"/>
+	<case id="1-240" unit="%" valid="true"/>
+	<case id="1-241" unit="/[HPF]" valid="true"/>
+	<case id="1-242" unit="/[LPF]" valid="true"/>
+	<case id="1-243" unit="/L" valid="true"/>
+	<case id="1-244" unit="/mL" valid="true"/>
+	<case id="1-245" unit="/mmol" valid="true"/>
+	<case id="1-246" unit="[APL'U]" valid="true"/>
+	<case id="1-247" unit="[BETH'U]" valid="false" reason="not a valid unit"/>
+	<case id="1-248" unit="[GPL'U]" valid="true"/>
+	<case id="1-249" unit="[IU]" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-250" unit="[IU]/d" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-251" unit="[IU]/L" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-252" unit="[IU]/mL" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-253" unit="[MPL'U]" valid="true"/>
+	<case id="1-254" unit="10*12/L" valid="true"/>
+	<case id="1-255" unit="10*6/L" valid="true"/>
+	<case id="1-256" unit="10*9/L" valid="true"/>
+	<case id="1-257" unit="Cel" valid="true"/>
+	<case id="1-258" unit="cm" valid="true"/>
+	<case id="1-259" unit="cm/s" valid="true"/>
+	<case id="1-260" unit="fL" valid="true"/>
+	<case id="1-261" unit="fmol/L" valid="true"/>
+	<case id="1-262" unit="g" valid="true"/>
+	<case id="1-263" unit="g/12h" valid="false" reason="not a valid unit (12h - should be 12.h)"/>
+	<case id="1-264" unit="g/48h" valid="false" reason="not a valid unit (48h)"/>
+	<case id="1-265" unit="g/4h" valid="false" reason="not a valid unit (4h)"/>
+	<case id="1-266" unit="g/6h" valid="false" reason="not a valid unit (6h)"/>
+	<case id="1-267" unit="g/72h" valid="false" reason="not a valid unit (72h)"/>
+	<case id="1-268" unit="g/d" valid="true"/>
+	<case id="1-269" unit="g/g" valid="true"/>
+	<case id="1-270" unit="g/L" valid="true"/>
+	<case id="1-271" unit="h" valid="true"/>
+	<case id="1-272" unit="km" valid="true"/>
+	<case id="1-273" unit="kU/L" valid="true"/>
+	<case id="1-274" unit="L/L" valid="true"/>
+	<case id="1-275" unit="m[IU]/L" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-276" unit="mg" valid="true"/>
+	<case id="1-277" unit="mg/12h" valid="false" reason="not a valid unit (12h)"/>
+	<case id="1-278" unit="mg/d" valid="true"/>
+	<case id="1-279" unit="mg/g" valid="true"/>
+	<case id="1-280" unit="mg/L" valid="true"/>
+	<case id="1-281" unit="mg/mg" valid="true"/>
+	<case id="1-282" unit="mg/mL" valid="true"/>
+	<case id="1-283" unit="min" valid="true"/>
+	<case id="1-284" unit="mL" valid="true"/>
+	<case id="1-285" unit="mL/10h" valid="false" reason="not a valid unit (10h)"/>
+	<case id="1-286" unit="mL/12h" valid="false" reason="not a valid unit (12h)"/>
+	<case id="1-287" unit="mL/2h" valid="false" reason="not a valid unit (2h)"/>
+	<case id="1-288" unit="mL/4h" valid="false" reason="not a valid unit (4h)"/>
+	<case id="1-289" unit="mL/5h" valid="false" reason="not a valid unit (5h)"/>
+	<case id="1-290" unit="mL/6h" valid="false" reason="not a valid unit (6h)"/>
+	<case id="1-291" unit="mL/72h" valid="false" reason="not a valid unit (72h)"/>
+	<case id="1-292" unit="mL/8h" valid="false" reason="not a valid unit (8h)"/>
+	<case id="1-293" unit="mL/d" valid="true"/>
+	<case id="1-294" unit="mL/min" valid="true"/>
+	<case id="1-295" unit="mm" valid="true"/>
+	<case id="1-296" unit="mm/h" valid="true"/>
+	<case id="1-297" unit="mm[Hg]" valid="true"/>
+	<case id="1-298" unit="mmol" valid="true"/>
+	<case id="1-299" unit="mmol/12h" valid="false" reason="not a valid unit (12h)"/>
+	<case id="1-300" unit="mmol/5h" valid="false" reason="not a valid unit (5h)"/>
+	<case id="1-301" unit="mmol/6h" valid="false" reason="not a valid unit (6h)"/>
+	<case id="1-302" unit="mmol/d" valid="true"/>
+	<case id="1-303" unit="mmol/g" valid="true"/>
+	<case id="1-304" unit="mmol/kg" valid="true"/>
+	<case id="1-305" unit="mmol/kg[H20]" valid="false" reason="not a valid unit (kg[H20])"/>
+	<case id="1-306" unit="mmol/L" valid="true"/>
+	<case id="1-307" unit="mmol/mmol" valid="true"/>
+	<case id="1-308" unit="mU/L" valid="true"/>
+	<case id="1-309" unit="ng/d" valid="true"/>
+	<case id="1-310" unit="ng/g" valid="true"/>
+	<case id="1-311" unit="ng/L" valid="true"/>
+	<case id="1-312" unit="ng/mL" valid="true"/>
+	<case id="1-313" unit="nmol/d" valid="true"/>
+	<case id="1-314" unit="nmol/g" valid="true"/>
+	<case id="1-315" unit="nmol/h/mL" valid="true"/>
+	<case id="1-316" unit="nmol/L" valid="true"/>
+	<case id="1-317" unit="nmol/mmol" valid="true"/>
+	<case id="1-318" unit="nmol/nmol" valid="true"/>
+	<case id="1-319" unit="pg" valid="true"/>
+	<case id="1-320" unit="pg/mL" valid="true"/>
+	<case id="1-321" unit="pmol/d" valid="true"/>
+	<case id="1-322" unit="pmol/g" valid="true"/>
+	<case id="1-323" unit="pmol/h/mg" valid="true"/>
+	<case id="1-324" unit="pmol/h/mL" valid="true"/>
+	<case id="1-325" unit="pmol/L" valid="true"/>
+	<case id="1-326" unit="pmol/mmol" valid="true"/>
+	<case id="1-327" unit="s" valid="true"/>
+	<case id="1-328" unit="U" valid="true"/>
+	<case id="1-329" unit="U/12h" valid="false" reason="not a valid unit (12h)"/>
+	<case id="1-330" unit="U/1h" valid="false" reason="not a valid unit (1h)"/>
+	<case id="1-331" unit="U/2h" valid="false" reason="not a valid unit (2h)"/>
+	<case id="1-332" unit="U/d" valid="true"/>
+	<case id="1-333" unit="U/g" valid="true"/>
+	<case id="1-334" unit="U/kg" valid="true"/>
+	<case id="1-335" unit="U/L" valid="true"/>
+	<case id="1-336" unit="U/mL" valid="true"/>
+	<case id="1-337" unit="u[IU]/mL" valid="false" reason="not a valid unit (iU)"/>
+	<case id="1-338" unit="ug" valid="true"/>
+	<case id="1-339" unit="ug/d" valid="true"/>
+	<case id="1-340" unit="ug/g" valid="true"/>
+	<case id="1-341" unit="ug/L" valid="true"/>
+	<case id="1-342" unit="ug/mL" valid="true"/>
+	<case id="1-343" unit="um/s" valid="true"/>
+	<case id="1-344" unit="umol" valid="true"/>
+	<case id="1-345" unit="umol/2.h" valid="true"/>
+	<case id="1-346" unit="umol/d" valid="true"/>
+	<case id="1-347" unit="umol/g" valid="true"/>
+	<case id="1-348" unit="umol/L" valid="true"/>
+	<case id="1-349" unit="umol/mmol" valid="true"/>
+	<case id="1-350" unit="umol/umol" valid="true"/>
+	<case id="1-351" unit="wk" valid="true"/>
+  </validation>	
+  
+  <displayNameGeneration>
+    <!-- 
+	  This is a somewhat trivial concept, but here to encourage standard practice 
+	  where it matters - the ability to take a code and produce a (slightly) more 
+	  human readable long form (might correspond to the HL7 v3 / ISO data types 
+	  concept of display name)
+	-->
+    <case id="2-101" unit="" display="1"/>
+	<case id="2-102" unit="m" display="(meter)"/>
+	<case id="2-103" unit="mm" display="(millimeter)"/>
+	<case id="2-104" unit="m[H2O]" display="(meter of water column)"/>
+	<case id="2-105" unit="10*23" display="(the number ten for arbitrary powers ^ 23)"/>
+	<case id="2-106" unit="rad2" display="(radian ^ 2)"/>
+	<case id="2-107" unit="m3.kg-1.s-2" display="(meter ^ 3) * (kilogram ^ -1) * (second ^ -2)"/>
+	<case id="2-108" unit="4.[pi].10*-7.N/A2" display="4 * (the number pi) * (the number ten for arbitrary powers ^ -7) * (Newton) / (Ampère ^ 2)"/>
+  </displayNameGeneration>		
+
+  
+  <conversion>
+    <!--
+	  Conversion Tests
+	  given value/srcUnit, what is the value in dstUnit?
+	  
+	  Note that we don't check directly what the canonical unit is. In fact,
+	  no particular form is actually defined for UCUM - it's up the implementor
+	  to define their own. However these tests check that the chosen canonical
+	  form is working correctly as they work, since it's required to perform 
+	  these conversions
+	-->
+    <case id="3-101" value="1"   srcUnit="m"      dstUnit="m"             outcome="1"/>
+    <case id="3-102" value="1"   srcUnit="mm"     dstUnit="m"             outcome="0.001"/>
+    <case id="3-103" value="10"  srcUnit="mm"     dstUnit="cm"            outcome="1.0"/>
+	<case id="3-104" value="1"   srcUnit="[in_i]" dstUnit="m"             outcome="0.0254"/>
+	<case id="3-105" value="1"   srcUnit="[in_i]" dstUnit="cm"            outcome="2.54"/>
+	<case id="3-106" value="1"   srcUnit="[mu_0]" dstUnit="g.m.C-2"       outcome="125663.7061435917295385057"/>
+	<case id="3-107" value="1"   srcUnit="m[Hg]"  dstUnit="g.s-2.m-1"     outcome="133322000"/> 
+	<case id="3-108" value="1"   srcUnit="S"      dstUnit="g-1.m-2.C2.s"  outcome="1000"/> 
+	<!--
+     Seiverts Canonicalisation (conceptual example):
+      S
+      Ohm-1
+      (V/A)-1
+      A/V
+      A/(J/C)
+      A/((N.m)/C)
+      A/(((kg.m/s2).m)/C)
+      (C/s)/(((g.m/s2).m)/C)
+      (C.s-1)/(((g.m/s2).m)/C)
+      (C.s-1)/(((g.m.s-2).m)/C)
+      (C.s-1)/(((g.m.s-2).m).C-1)
+      (C.s-1)/(g.m.s-2.m.C-1)
+      (C.s-1).(g-1.m-1.s2.m-1.C)
+      C.s-1.g-1.m-1.s2.m-1.C
+      C2.m-2.s.g-1	
+      C2.g-1.m-2.s	(alphabetical)
+	-->
+	<case id="3-109" value="1"   srcUnit="[ly]"   dstUnit="cm"            outcome="946073047258080000"/>
+	<case id="3-110" value="1.2" srcUnit="g.m"    dstUnit="m.g"           outcome="1.2"/>
+  </conversion>
+
+  <multiplication>
+    <!-- 
+	  Given v1/u1, and v2/u2, multiply them together - should get something that is canonically equal
+	  to vRes/uRes. Note that it doesn't have to be the same as vRes/uRes: the units 
+	  reported may differ in order or some other form, and the value may consequently 
+	  be different, but the result must convert to the stated value
+	-->
+    <case id="4-101" v1="1.5" u1="g" v2="2" u2="m" vRes="3" uRes="g.m"/>
+  </multiplication>
+  
+  
+</ucumTests>
+  
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/H3ETTestConfiguration.java b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/H3ETTestConfiguration.java
new file mode 100644
index 0000000..4a28125
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/H3ETTestConfiguration.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.tests;
+
+//import org.eclipse.uomo.util.test.UOMoTestConfiguration;
+
+
+
+/*
+ * we need some ideas here. 
+ * 1. copyright. The testing uses a sample project. It's full of things that are open but
+ *    not sufficiently unencumbered to be EPL. So it's on
+ *    sourceforge @ https://sourceforge.net/projects/ohf-he3t-test
+ * 
+ * 2. Local directory. We've given up trying to organise some better way to 
+ *    organise where the data resides. So it's a constant here, and you simply
+ *    change the constant for your local setup.
+ *    
+ *     Better ideas are welcome
+ */
+
+public interface H3ETTestConfiguration   {
+	
+	/**
+	 * The test workspace, which should contains the test project
+	 * org.eclipse.ohf.h3et.test
+	 * 
+	 * NOTE: current setting assume the test workspace contains two projects:
+	 * * org.eclipse.ohf.h3et.test: with a minimised MIF and its related test data
+	 * * ca.infoway.cerx.mif21: Using the Infoway MIFs settings for more general testing 
+	 */
+	public static final String TEST_WORKSPACE = System.getenv("WORKSPACE") != null ? System.getenv("WORKSPACE") : "C:/workspace/data/";
+//	public static final String TEST_PROJECT 			= TEST_WORKSPACE + "org.eclipse.ohf.h3et.test";
+//	public static final String TEST_PROJECT_VOCAB 		= TEST_PROJECT+"/Vocab";
+//	public static final String TEST_PROJECT_MIF 		= TEST_PROJECT+"/Mif";
+//	public static final String TEST_PROJECT_CASES 		= TEST_PROJECT+"/TestCases";
+//	public static final String TEST_PROJECT_FRAGMENTS 	= TEST_PROJECT+"/Mif/Fragments";
+	
+	public static final String WORK_PROJECT 			= TEST_WORKSPACE + "ca.infoway.cerx.mif21";
+	public static final String WORK_PROJECT_VOCAB 		= WORK_PROJECT+"/Vocab";
+	public static final String WORK_PROJECT_MIF 		= WORK_PROJECT+"/Mif";
+	public static final String WORK_PROJECT_CASES 		= WORK_PROJECT+"/TestCases";
+	public static final String WORK_PROJECT_FRAGMENTS 	= WORK_PROJECT+"/Mif/Fragments";
+	public static final String WORK_PROJECT_TESTFOLDER	= WORK_PROJECT+"/unitTests";
+	
+}
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/SystemTest.java b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/SystemTest.java
new file mode 100644
index 0000000..c052ac7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/SystemTest.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.ucum.tests;
+import static org.eclipse.uomo.core.impl.OutputHelper.print;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+
+/**
+ * @author Werner Keil
+ *
+ */
+public class SystemTest {
+	
+	@Test
+	public void testEnv() {
+		Map<String, String> env = System.getenv();
+		assertNotNull(env);
+		assertNotNull(env.values());
+		assertTrue(env.values().size()>0);
+		for (String value : env.values()) {
+			print(value);
+		}		
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumServiceTest.java b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumServiceTest.java
new file mode 100644
index 0000000..bce45dd
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumServiceTest.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Werner Keil.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.ucum.tests;
+
+import static org.junit.Assert.*;
+import static org.eclipse.uomo.core.impl.OutputHelper.*;
+import java.math.BigDecimal;
+import java.util.Set;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.ucum.UcumService;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+import org.eclipse.uomo.ucum.impl.UcumEssenceService;
+import org.eclipse.uomo.ucum.parsers.ExpressionParser;
+import org.eclipse.uomo.util.Parser;
+import org.junit.Before;
+import org.junit.Test;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.text.DecimalFormat;
+import com.ibm.icu.text.NumberFormat;
+
+
+/**
+ * @author Werner Keil
+ * @version 1.2, 2013-04-28
+ */
+public class UcumServiceTest {
+	private UcumService ucumService;
+	
+	@Before
+	public void init() {
+		if (ucumService == null) {
+			ucumService = new UcumEssenceService(getClass().getClassLoader().getResourceAsStream("ucum-essence.xml"));
+		}
+	}
+	
+	@Test
+	public void testConversion() {
+		Number mult = ucumService.convert(new BigDecimal(1000d), "l", "m3");
+		assertNotNull(mult);		
+		NumberFormat fmt = new DecimalFormat("#,##0.000");
+		assertEquals(fmt.format(BigDecimal.ONE), fmt.format(mult));
+	}
+
+	@Test
+	public void testProperties() {
+		Set<String> props = ucumService.getProperties();
+		if (isConsoleOutput()) {
+			for (String prop : props) {
+				println(prop);
+			}
+		}
+		assertTrue(props.size() == 92);
+	}
+	
+	
+	@Test
+	public void testParse() {
+		Parser<String, Term> p = new ExpressionParser(ucumService.getModel());
+		try {
+			Term t =  p.parse("m/s2");
+			assertNotNull(t);
+			assertEquals("DIVISION", t.getOp().toString());
+			Symbol s = (Symbol)t.getComp();
+			Unit<?> u = s.getUnit();
+			assertEquals("m", u.getSymbol());
+		} catch (UOMoException e) {
+			println(e.getLocalizedMessage());
+			fail(e.getLocalizedMessage());
+		}
+	}
+	
+	@Test
+	public void testParseParseMult1() {
+		Parser<String, Term> p = new ExpressionParser(ucumService.getModel());
+		try {
+			Term t =  p.parse("m.s2");
+			assertNotNull(t);
+			assertEquals("MULTIPLICATION", t.getOp().toString());
+			Symbol s = (Symbol)t.getComp();
+			Unit<?> u = s.getUnit();
+			assertEquals("m", u.getSymbol());
+		} catch (UOMoException e) {
+			println(e.getLocalizedMessage());
+			fail(e.getLocalizedMessage());
+		}
+	}
+	
+	/**
+	 * @see <a
+     *  href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=371433">Bugzilla: 371433</a>
+	 */
+	@Test
+	public void testParseParseParenthes1() {
+		Parser<String, Term> p = new ExpressionParser(ucumService.getModel());
+		try {
+			Term t =  p.parse("kg/m/s");
+			assertNotNull(t);
+			assertEquals("DIVISION", t.getOp().toString());
+			Symbol s = (Symbol)t.getComp();
+			Unit<?> u = s.getUnit();
+			assertEquals("g", u.getSymbol());
+			assertEquals("k", s.getPrefix().getSymbol());
+		} catch (UOMoException e) {
+			println(e.getLocalizedMessage());
+			fail(e.getLocalizedMessage());
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumTestSuite.java b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumTestSuite.java
new file mode 100644
index 0000000..e5a4dbe
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/UcumTestSuite.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2008, 2011, Kestral Computing, (c) 2012, 2013 Werner Keil.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing - initial API and implementation
+ *    Werner Keil - refactoring and improvements
+ *******************************************************************************/
+package org.eclipse.uomo.ucum.tests;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+
+/**
+ * @author dennisn
+ * @author Werner Keil
+ */
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	SystemTest.class, UcumServiceTest.class
+})
+public class UcumTestSuite {
+
+	/**
+	 * For use with JUnit3 runner
+	 * @deprecated
+	 */
+	public static Test suite() {
+		return new JUnit4TestAdapter(UcumTestSuite.class);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/package-info.java b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/package-info.java
new file mode 100644
index 0000000..d8f7c0b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/org/eclipse/uomo/ucum/tests/package-info.java
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) 2010-2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+/**
+ * @author Werner Keil
+ *
+ */
+package org.eclipse.uomo.ucum.tests;
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum.tests/src/ucum-essence.xml b/bundles/org.eclipse.uomo.ucum.tests/src/ucum-essence.xml
new file mode 100644
index 0000000..e7c9e49
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum.tests/src/ucum-essence.xml
@@ -0,0 +1,1947 @@
+<?xml version="1.0" encoding="ascii"?>
+<root version="1.8.2" revision="$Revision: 16398 $"
+      revision-date="$Date: 2012-10-30 18:11:49 -0700 (Tue, 30 Oct 2012) $">
+   <prefix Code="Y" CODE="YA">
+      <name>yotta</name>
+      <printSymbol>Y</printSymbol>
+      <value value="1e24">1 &#215; 10<sup>24</sup>
+      </value>
+   </prefix>
+   <prefix Code="Z" CODE="ZA">
+      <name>zetta</name>
+      <printSymbol>Z</printSymbol>
+      <value value="1e21">1 &#215; 10<sup>21</sup>
+      </value>
+   </prefix>
+   <prefix Code="E" CODE="EX">
+      <name>exa</name>
+      <printSymbol>E</printSymbol>
+      <value value="1e18">1 &#215; 10<sup>18</sup>
+      </value>
+   </prefix>
+   <prefix Code="P" CODE="PT">
+      <name>peta</name>
+      <printSymbol>P</printSymbol>
+      <value value="1e15">1 &#215; 10<sup>15</sup>
+      </value>
+   </prefix>
+   <prefix Code="T" CODE="TR">
+      <name>tera</name>
+      <printSymbol>T</printSymbol>
+      <value value="1e12">1 &#215; 10<sup>12</sup>
+      </value>
+   </prefix>
+   <prefix Code="G" CODE="GA">
+      <name>giga</name>
+      <printSymbol>G</printSymbol>
+      <value value="1e9">1 &#215; 10<sup>9</sup>
+      </value>
+   </prefix>
+   <prefix Code="M" CODE="MA">
+      <name>mega</name>
+      <printSymbol>M</printSymbol>
+      <value value="1e6">1 &#215; 10<sup>6</sup>
+      </value>
+   </prefix>
+   <prefix Code="k" CODE="K">
+      <name>kilo</name>
+      <printSymbol>k</printSymbol>
+      <value value="1e3">1 &#215; 10<sup>3</sup>
+      </value>
+   </prefix>
+   <prefix Code="h" CODE="H">
+      <name>hecto</name>
+      <printSymbol>h</printSymbol>
+      <value value="1e2">1 &#215; 10<sup>2</sup>
+      </value>
+   </prefix>
+   <prefix Code="da" CODE="DA">
+      <name>deka</name>
+      <printSymbol>da</printSymbol>
+      <value value="1e1">1 &#215; 10<sup>1</sup>
+      </value>
+   </prefix>
+   <prefix Code="d" CODE="D">
+      <name>deci</name>
+      <printSymbol>d</printSymbol>
+      <value value="1e-1">1 &#215; 10<sup>-1</sup>
+      </value>
+   </prefix>
+   <prefix Code="c" CODE="C">
+      <name>centi</name>
+      <printSymbol>c</printSymbol>
+      <value value="1e-2">1 &#215; 10<sup>-2</sup>
+      </value>
+   </prefix>
+   <prefix Code="m" CODE="M">
+      <name>milli</name>
+      <printSymbol>m</printSymbol>
+      <value value="1e-3">1 &#215; 10<sup>-3</sup>
+      </value>
+   </prefix>
+   <prefix Code="u" CODE="U">
+      <name>micro</name>
+      <printSymbol>&#956;</printSymbol>
+      <value value="1e-6">1 &#215; 10<sup>-6</sup>
+      </value>
+   </prefix>
+   <prefix Code="n" CODE="N">
+      <name>nano</name>
+      <printSymbol>n</printSymbol>
+      <value value="1e-9">1 &#215; 10<sup>-9</sup>
+      </value>
+   </prefix>
+   <prefix Code="p" CODE="P">
+      <name>pico</name>
+      <printSymbol>p</printSymbol>
+      <value value="1e-12">1 &#215; 10<sup>-12</sup>
+      </value>
+   </prefix>
+   <prefix Code="f" CODE="F">
+      <name>femto</name>
+      <printSymbol>f</printSymbol>
+      <value value="1e-15">1 &#215; 10<sup>-15</sup>
+      </value>
+   </prefix>
+   <prefix Code="a" CODE="A">
+      <name>atto</name>
+      <printSymbol>a</printSymbol>
+      <value value="1e-18">1 &#215; 10<sup>-18</sup>
+      </value>
+   </prefix>
+   <prefix Code="z" CODE="ZO">
+      <name>zepto</name>
+      <printSymbol>z</printSymbol>
+      <value value="1e-21">1 &#215; 10<sup>-21</sup>
+      </value>
+   </prefix>
+   <prefix Code="y" CODE="YO">
+      <name>yocto</name>
+      <printSymbol>y</printSymbol>
+      <value value="1e-24">1 &#215; 10<sup>-24</sup>
+      </value>
+   </prefix>
+   <base-unit Code="m" CODE="M" dim="L">
+      <name>meter</name>
+      <printSymbol>m</printSymbol>
+      <property>length</property>
+   </base-unit>
+   <base-unit Code="s" CODE="S" dim="T">
+      <name>second</name>
+      <printSymbol>s</printSymbol>
+      <property>time</property>
+   </base-unit>
+   <base-unit Code="g" CODE="G" dim="M">
+      <name>gram</name>
+      <printSymbol>g</printSymbol>
+      <property>mass</property>
+   </base-unit>
+   <base-unit Code="rad" CODE="RAD" dim="A">
+      <name>radian</name>
+      <printSymbol>rad</printSymbol>
+      <property>plane angle</property>
+   </base-unit>
+   <base-unit Code="K" CODE="K" dim="C">
+      <name>Kelvin</name>
+      <printSymbol>K</printSymbol>
+      <property>temperature</property>
+   </base-unit>
+   <base-unit Code="C" CODE="C" dim="Q">
+      <name>Coulomb</name>
+      <printSymbol>C</printSymbol>
+      <property>electric charge</property>
+   </base-unit>
+   <base-unit Code="cd" CODE="CD" dim="F">
+      <name>candela</name>
+      <printSymbol>cd</printSymbol>
+      <property>luminous intensity</property>
+   </base-unit>
+   <unit Code="10*" CODE="10*" isMetric="no" class="dimless">
+      <name>the number ten for arbitrary powers</name>
+      <printSymbol>10</printSymbol>
+      <property>number</property>
+      <value Unit="1" UNIT="1" value="10">10</value>
+   </unit>
+   <unit Code="10^" CODE="10^" isMetric="no" class="dimless">
+      <name>the number ten for arbitrary powers</name>
+      <printSymbol>10</printSymbol>
+      <property>number</property>
+      <value Unit="1" UNIT="1" value="10">10</value>
+   </unit>
+   <unit Code="[pi]" CODE="[PI]" isMetric="no" class="dimless">
+      <name>the number pi</name>
+      <printSymbol>&#960;</printSymbol>
+      <property>number</property>
+      <value Unit="1" UNIT="1"
+             value="3.1415926535897932384626433832795028841971693993751058209749445923">&#960;</value>
+   </unit>
+   <unit Code="%" CODE="%" isMetric="no" class="dimless">
+      <name>percent</name>
+      <printSymbol>%</printSymbol>
+      <property>fraction</property>
+      <value Unit="10*-2" UNIT="10*-2" value="1">1</value>
+   </unit>
+   <unit Code="[ppth]" CODE="[PPTH]" isMetric="no" class="dimless">
+      <name>parts per thousand</name>
+      <printSymbol>ppth</printSymbol>
+      <property>fraction</property>
+      <value Unit="10*-3" UNIT="10*-3" value="1">1</value>
+   </unit>
+   <unit Code="[ppm]" CODE="[PPM]" isMetric="no" class="dimless">
+      <name>parts per million</name>
+      <printSymbol>ppm</printSymbol>
+      <property>fraction</property>
+      <value Unit="10*-6" UNIT="10*-6" value="1">1</value>
+   </unit>
+   <unit Code="[ppb]" CODE="[PPB]" isMetric="no" class="dimless">
+      <name>parts per billion</name>
+      <printSymbol>ppb</printSymbol>
+      <property>fraction</property>
+      <value Unit="10*-9" UNIT="10*-9" value="1">1</value>
+   </unit>
+   <unit Code="[pptr]" CODE="[PPTR]" isMetric="no" class="dimless">
+      <name>parts per trillion</name>
+      <printSymbol>pptr</printSymbol>
+      <property>fraction</property>
+      <value Unit="10*-12" UNIT="10*-12" value="1">1</value>
+   </unit>
+   <unit Code="mol" CODE="MOL" isMetric="yes" class="si">
+      <name>mole</name>
+      <printSymbol>mol</printSymbol>
+      <property>amount of substance</property>
+      <value Unit="10*23" UNIT="10*23" value="6.0221367">6.0221367</value>
+   </unit>
+   <unit Code="sr" CODE="SR" isMetric="yes" class="si">
+      <name>steradian</name>
+      <printSymbol>sr</printSymbol>
+      <property>solid angle</property>
+      <value Unit="rad2" UNIT="RAD2" value="1">1</value>
+   </unit>
+   <unit Code="Hz" CODE="HZ" isMetric="yes" class="si">
+      <name>Hertz</name>
+      <printSymbol>Hz</printSymbol>
+      <property>frequency</property>
+      <value Unit="s-1" UNIT="S-1" value="1">1</value>
+   </unit>
+   <unit Code="N" CODE="N" isMetric="yes" class="si">
+      <name>Newton</name>
+      <printSymbol>N</printSymbol>
+      <property>force</property>
+      <value Unit="kg.m/s2" UNIT="KG.M/S2" value="1">1</value>
+   </unit>
+   <unit Code="Pa" CODE="PAL" isMetric="yes" class="si">
+      <name>Pascal</name>
+      <printSymbol>Pa</printSymbol>
+      <property>pressure</property>
+      <value Unit="N/m2" UNIT="N/M2" value="1">1</value>
+   </unit>
+   <unit Code="J" CODE="J" isMetric="yes" class="si">
+      <name>Joule</name>
+      <printSymbol>J</printSymbol>
+      <property>energy</property>
+      <value Unit="N.m" UNIT="N.M" value="1">1</value>
+   </unit>
+   <unit Code="W" CODE="W" isMetric="yes" class="si">
+      <name>Watt</name>
+      <printSymbol>W</printSymbol>
+      <property>power</property>
+      <value Unit="J/s" UNIT="J/S" value="1">1</value>
+   </unit>
+   <unit Code="A" CODE="A" isMetric="yes" class="si">
+      <name>Amp&#232;re</name>
+      <printSymbol>A</printSymbol>
+      <property>electric current</property>
+      <value Unit="C/s" UNIT="C/S" value="1">1</value>
+   </unit>
+   <unit Code="V" CODE="V" isMetric="yes" class="si">
+      <name>Volt</name>
+      <printSymbol>V</printSymbol>
+      <property>electric potential</property>
+      <value Unit="J/C" UNIT="J/C" value="1">1</value>
+   </unit>
+   <unit Code="F" CODE="F" isMetric="yes" class="si">
+      <name>Farad</name>
+      <printSymbol>F</printSymbol>
+      <property>electric capacitance</property>
+      <value Unit="C/V" UNIT="C/V" value="1">1</value>
+   </unit>
+   <unit Code="Ohm" CODE="OHM" isMetric="yes" class="si">
+      <name>Ohm</name>
+      <printSymbol>&#937;</printSymbol>
+      <property>electric resistance</property>
+      <value Unit="V/A" UNIT="V/A" value="1">1</value>
+   </unit>
+   <unit Code="S" CODE="SIE" isMetric="yes" class="si">
+      <name>Siemens</name>
+      <printSymbol>S</printSymbol>
+      <property>electric conductance</property>
+      <value Unit="Ohm-1" UNIT="OHM-1" value="1">1</value>
+   </unit>
+   <unit Code="Wb" CODE="WB" isMetric="yes" class="si">
+      <name>Weber</name>
+      <printSymbol>Wb</printSymbol>
+      <property>magentic flux</property>
+      <value Unit="V.s" UNIT="V.S" value="1">1</value>
+   </unit>
+   <unit Code="Cel" CODE="CEL" isMetric="yes" isSpecial="yes" class="si">
+      <name>degree Celsius</name>
+      <printSymbol>&#176;C</printSymbol>
+      <property>temperature</property>
+      <value Unit="cel(1 K)" UNIT="CEL(1 K)">
+         <function name="Cel" value="1" Unit="K"/>
+      </value>
+   </unit>
+   <unit Code="T" CODE="T" isMetric="yes" class="si">
+      <name>Tesla</name>
+      <printSymbol>T</printSymbol>
+      <property>magnetic flux density</property>
+      <value Unit="Wb/m2" UNIT="WB/M2" value="1">1</value>
+   </unit>
+   <unit Code="H" CODE="H" isMetric="yes" class="si">
+      <name>Henry</name>
+      <printSymbol>H</printSymbol>
+      <property>inductance</property>
+      <value Unit="Wb/A" UNIT="WB/A" value="1">1</value>
+   </unit>
+   <unit Code="lm" CODE="LM" isMetric="yes" class="si">
+      <name>lumen</name>
+      <printSymbol>lm</printSymbol>
+      <property>luminous flux</property>
+      <value Unit="cd.sr" UNIT="CD.SR" value="1">1</value>
+   </unit>
+   <unit Code="lx" CODE="LX" isMetric="yes" class="si">
+      <name>lux</name>
+      <printSymbol>lx</printSymbol>
+      <property>illuminance</property>
+      <value Unit="lm/m2" UNIT="LM/M2" value="1">1</value>
+   </unit>
+   <unit Code="Bq" CODE="BQ" isMetric="yes" class="si">
+      <name>Becquerel</name>
+      <printSymbol>Bq</printSymbol>
+      <property>radioactivity</property>
+      <value Unit="s-1" UNIT="S-1" value="1">1</value>
+   </unit>
+   <unit Code="Gy" CODE="GY" isMetric="yes" class="si">
+      <name>Gray</name>
+      <printSymbol>Gy</printSymbol>
+      <property>energy dose</property>
+      <value Unit="J/kg" UNIT="J/KG" value="1">1</value>
+   </unit>
+   <unit Code="Sv" CODE="SV" isMetric="yes" class="si">
+      <name>Sievert</name>
+      <printSymbol>Sv</printSymbol>
+      <property>dose equivalent</property>
+      <value Unit="J/kg" UNIT="J/KG" value="1">1</value>
+   </unit>
+   <unit Code="gon" CODE="GON" isMetric="no" class="iso1000">
+      <name>gon</name>
+      <name>grade</name>
+      <printSymbol>&#9633;<sup>g</sup>
+      </printSymbol>
+      <property>plane angle</property>
+      <value Unit="deg" UNIT="DEG" value="0.9">0.9</value>
+   </unit>
+   <unit Code="deg" CODE="DEG" isMetric="no" class="iso1000">
+      <name>degree</name>
+      <printSymbol>&#176;</printSymbol>
+      <property>plane angle</property>
+      <value Unit="[pi].rad/360" UNIT="[PI].RAD/360" value="2">2</value>
+   </unit>
+   <unit Code="'" CODE="'" isMetric="no" class="iso1000">
+      <name>minute</name>
+      <printSymbol>'</printSymbol>
+      <property>plane angle</property>
+      <value Unit="deg/60" UNIT="DEG/60" value="1">1</value>
+   </unit>
+   <unit Code="''" CODE="''" isMetric="no" class="iso1000">
+      <name>second</name>
+      <printSymbol>''</printSymbol>
+      <property>plane angle</property>
+      <value Unit="'/60" UNIT="'/60" value="1">1</value>
+   </unit>
+   <unit Code="l" CODE="L" isMetric="yes" class="iso1000">
+      <name>liter</name>
+      <printSymbol>l</printSymbol>
+      <property>volume</property>
+      <value Unit="dm3" UNIT="DM3" value="1">1</value>
+   </unit>
+   <unit Code="L" isMetric="yes" class="iso1000">
+      <name>liter</name>
+      <printSymbol>L</printSymbol>
+      <property>volume</property>
+      <value Unit="l" value="1">1</value>
+   </unit>
+   <unit Code="ar" CODE="AR" isMetric="yes" class="iso1000">
+      <name>are</name>
+      <printSymbol>a</printSymbol>
+      <property>area</property>
+      <value Unit="m2" UNIT="M2" value="100">100</value>
+   </unit>
+   <unit Code="min" CODE="MIN" isMetric="no" class="iso1000">
+      <name>minute</name>
+      <printSymbol>min</printSymbol>
+      <property>time</property>
+      <value Unit="s" UNIT="S" value="60">60</value>
+   </unit>
+   <unit Code="h" CODE="HR" isMetric="no" class="iso1000">
+      <name>hour</name>
+      <printSymbol>h</printSymbol>
+      <property>time</property>
+      <value Unit="min" UNIT="MIN" value="60">60</value>
+   </unit>
+   <unit Code="d" CODE="D" isMetric="no" class="iso1000">
+      <name>day</name>
+      <printSymbol>d</printSymbol>
+      <property>time</property>
+      <value Unit="h" UNIT="HR" value="24">24</value>
+   </unit>
+   <unit Code="a_t" CODE="ANN_T" isMetric="no" class="iso1000">
+      <name>tropical year</name>
+      <printSymbol>a<sub>t</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="d" UNIT="D" value="365.24219">365.24219</value>
+   </unit>
+   <unit Code="a_j" CODE="ANN_J" isMetric="no" class="iso1000">
+      <name>mean Julian year</name>
+      <printSymbol>a<sub>j</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="d" UNIT="D" value="365.25">365.25</value>
+   </unit>
+   <unit Code="a_g" CODE="ANN_G" isMetric="no" class="iso1000">
+      <name>mean Gregorian year</name>
+      <printSymbol>a<sub>g</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="d" UNIT="D" value="365.2425">365.2425</value>
+   </unit>
+   <unit Code="a" CODE="ANN" isMetric="no" class="iso1000">
+      <name>year</name>
+      <printSymbol>a</printSymbol>
+      <property>time</property>
+      <value Unit="a_j" UNIT="ANN_J" value="1">1</value>
+   </unit>
+   <unit Code="wk" CODE="WK" isMetric="no" class="iso1000">
+      <name>week</name>
+      <printSymbol>wk</printSymbol>
+      <property>time</property>
+      <value Unit="d" UNIT="D" value="7">7</value>
+   </unit>
+   <unit Code="mo_s" CODE="MO_S" isMetric="no" class="iso1000">
+      <name>synodal month</name>
+      <printSymbol>mo<sub>s</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="d" UNIT="D" value="29.53059">29.53059</value>
+   </unit>
+   <unit Code="mo_j" CODE="MO_J" isMetric="no" class="iso1000">
+      <name>mean Julian month</name>
+      <printSymbol>mo<sub>j</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="a_j/12" UNIT="ANN_J/12" value="1">1</value>
+   </unit>
+   <unit Code="mo_g" CODE="MO_G" isMetric="no" class="iso1000">
+      <name>mean Gregorian month</name>
+      <printSymbol>mo<sub>g</sub>
+      </printSymbol>
+      <property>time</property>
+      <value Unit="a_g/12" UNIT="ANN_G/12" value="1">1</value>
+   </unit>
+   <unit Code="mo" CODE="MO" isMetric="no" class="iso1000">
+      <name>month</name>
+      <printSymbol>mo</printSymbol>
+      <property>time</property>
+      <value Unit="mo_j" UNIT="MO_J" value="1">1</value>
+   </unit>
+   <unit Code="t" CODE="TNE" isMetric="yes" class="iso1000">
+      <name>tonne</name>
+      <printSymbol>t</printSymbol>
+      <property>mass</property>
+      <value Unit="kg" UNIT="KG" value="1e3">1 &#215; 10<sup>3</sup>
+      </value>
+   </unit>
+   <unit Code="bar" CODE="BAR" isMetric="yes" class="iso1000">
+      <name>bar</name>
+      <printSymbol>bar</printSymbol>
+      <property>pressure</property>
+      <value Unit="Pa" UNIT="PAL" value="1e5">1 &#215; 10<sup>5</sup>
+      </value>
+   </unit>
+   <unit Code="u" CODE="AMU" isMetric="yes" class="iso1000">
+      <name>unified atomic mass unit</name>
+      <printSymbol>u</printSymbol>
+      <property>mass</property>
+      <value Unit="g" UNIT="G" value="1.6605402e-24">1.6605402 &#215; 10<sup>-24</sup>
+      </value>
+   </unit>
+   <unit Code="eV" CODE="EV" isMetric="yes" class="iso1000">
+      <name>electronvolt</name>
+      <printSymbol>eV</printSymbol>
+      <property>energy</property>
+      <value Unit="[e].V" UNIT="[E].V" value="1">1</value>
+   </unit>
+   <unit Code="AU" CODE="ASU" isMetric="no" class="iso1000">
+      <name>astronomic unit</name>
+      <printSymbol>AU</printSymbol>
+      <property>length</property>
+      <value Unit="Mm" UNIT="MAM" value="149597.870">149597.870</value>
+   </unit>
+   <unit Code="pc" CODE="PRS" isMetric="yes" class="iso1000">
+      <name>parsec</name>
+      <printSymbol>pc</printSymbol>
+      <property>length</property>
+      <value Unit="m" UNIT="M" value="3.085678e16">3.085678 &#215; 10<sup>16</sup>
+      </value>
+   </unit>
+   <unit Code="[c]" CODE="[C]" isMetric="yes" class="const">
+      <name>velocity of light</name>
+      <printSymbol>
+         <i>c</i>
+      </printSymbol>
+      <property>velocity</property>
+      <value Unit="m/s" UNIT="M/S" value="299792458">299792458</value>
+   </unit>
+   <unit Code="[h]" CODE="[H]" isMetric="yes" class="const">
+      <name>Planck constant</name>
+      <printSymbol>
+         <i>h</i>
+      </printSymbol>
+      <property>action</property>
+      <value Unit="J.s" UNIT="J.S" value="6.6260755e-24">6.6260755 &#215; 10<sup>-24</sup>
+      </value>
+   </unit>
+   <unit Code="[k]" CODE="[K]" isMetric="yes" class="const">
+      <name>Boltzmann constant</name>
+      <printSymbol>
+         <i>k</i>
+      </printSymbol>
+      <property>(unclassified)</property>
+      <value Unit="J/K" UNIT="J/K" value="1.380658e-23">1.380658 &#215; 10<sup>-23</sup>
+      </value>
+   </unit>
+   <unit Code="[eps_0]" CODE="[eps_0]" isMetric="yes" class="const">
+      <name>permittivity of vacuum</name>
+      <printSymbol>
+         <i>&#949;<sub>
+               <r>0</r>
+            </sub>
+         </i>
+      </printSymbol>
+      <property>electric permittivity</property>
+      <value Unit="F/m" UNIT="F/M" value="8.854187817e-12">8.854187817 &#215; 10<sup>-12</sup>
+      </value>
+   </unit>
+   <unit Code="[mu_0]" CODE="[mu_0]" isMetric="yes" class="const">
+      <name>permeability of vacuum</name>
+      <printSymbol>
+         <i>&#956;<sub>
+               <r>0</r>
+            </sub>
+         </i>
+      </printSymbol>
+      <property>magnetic permeability</property>
+      <value Unit="4.[pi].10*-7.N/A2" UNIT="4.[PI].10*-7.N/A2" value="1">1</value>
+   </unit>
+   <unit Code="[e]" CODE="[E]" isMetric="yes" class="const">
+      <name>elementary charge</name>
+      <printSymbol>
+         <i>e</i>
+      </printSymbol>
+      <property>electric charge</property>
+      <value Unit="C" UNIT="C" value="1.60217733e-19">1.60217733 &#215; 10<sup>-19</sup>
+      </value>
+   </unit>
+   <unit Code="[m_e]" CODE="[M_E]" isMetric="yes" class="const">
+      <name>electron mass</name>
+      <printSymbol>
+         <i>m<sub>
+               <r>e</r>
+            </sub>
+         </i>
+      </printSymbol>
+      <property>mass</property>
+      <value Unit="g" UNIT="g" value="9.1093897e-28">9.1093897 &#215; 10<sup>-28</sup>
+      </value>
+   </unit>
+   <unit Code="[m_p]" CODE="[M_P]" isMetric="yes" class="const">
+      <name>proton mass</name>
+      <printSymbol>
+         <i>m<sub>
+               <r>p</r>
+            </sub>
+         </i>
+      </printSymbol>
+      <property>mass</property>
+      <value Unit="g" UNIT="g" value="1.6726231e-24">1.6726231 &#215; 10<sup>-24</sup>
+      </value>
+   </unit>
+   <unit Code="[G]" CODE="[GC]" isMetric="yes" class="const">
+      <name>Newtonian constant of gravitation</name>
+      <printSymbol>
+         <i>G</i>
+      </printSymbol>
+      <property>(unclassified)</property>
+      <value Unit="m3.kg-1.s-2" UNIT="M3.KG-1.S-2" value="6.67259e-11">6.67259 &#215; 10<sup>-11</sup>
+      </value>
+   </unit>
+   <unit Code="[g]" CODE="[G]" isMetric="yes" class="const">
+      <name>standard acceleration of free fall</name>
+      <printSymbol>
+         <i>g<sub>n</sub>
+         </i>
+      </printSymbol>
+      <property>acceleration</property>
+      <value Unit="m/s2" UNIT="M/S" value="9.80665">9.80665</value>
+   </unit>
+   <unit Code="atm" CODE="ATM" isMetric="no" class="const">
+      <name>standard atmosphere</name>
+      <printSymbol>atm</printSymbol>
+      <property>pressure</property>
+      <value Unit="Pa" UNIT="KPAL" value="101325">101325</value>
+   </unit>
+   <unit Code="[ly]" CODE="[LY]" isMetric="yes" class="const">
+      <name>light-year</name>
+      <printSymbol>l.y.</printSymbol>
+      <property>length</property>
+      <value Unit="[c].a_j" UNIT="[C].ANN_J" value="1">1</value>
+   </unit>
+   <unit Code="gf" CODE="GF" isMetric="yes" class="const">
+      <name>gram-force</name>
+      <printSymbol>gf</printSymbol>
+      <property>force</property>
+      <value Unit="g.[g]" UNIT="G.[G]" value="1">1</value>
+   </unit>
+   <unit Code="[lbf_av]" CODE="[LBF_AV]" isMetric="no" class="const">
+      <name>pound force</name>
+      <printSymbol>lbf</printSymbol>
+      <property>force</property>
+      <value Unit="[lb_av].[g]" UNIT="[LB_AV].[G]" value="1">1</value>
+   </unit>
+   <unit Code="Ky" CODE="KY" isMetric="yes" class="cgs">
+      <name>Kayser</name>
+      <printSymbol>K</printSymbol>
+      <property>lineic number</property>
+      <value Unit="cm-1" UNIT="CM-1" value="1">1</value>
+   </unit>
+   <unit Code="Gal" CODE="GL" isMetric="yes" class="cgs">
+      <name>Gal</name>
+      <printSymbol>Gal</printSymbol>
+      <property>acceleration</property>
+      <value Unit="cm/s2" UNIT="CM/S2" value="1">1</value>
+   </unit>
+   <unit Code="dyn" CODE="DYN" isMetric="yes" class="cgs">
+      <name>dyne</name>
+      <printSymbol>dyn</printSymbol>
+      <property>force</property>
+      <value Unit="g.cm/s2" UNIT="G.CM/S2" value="1">1</value>
+   </unit>
+   <unit Code="erg" CODE="ERG" isMetric="yes" class="cgs">
+      <name>erg</name>
+      <printSymbol>erg</printSymbol>
+      <property>energy</property>
+      <value Unit="dyn.cm" UNIT="DYN.CM" value="1">1</value>
+   </unit>
+   <unit Code="P" CODE="P" isMetric="yes" class="cgs">
+      <name>Poise</name>
+      <printSymbol>P</printSymbol>
+      <property>dynamic viscosity</property>
+      <value Unit="dyn.s/cm2" UNIT="DYN.S/CM2" value="1">1</value>
+   </unit>
+   <unit Code="Bi" CODE="BI" isMetric="yes" class="cgs">
+      <name>Biot</name>
+      <printSymbol>Bi</printSymbol>
+      <property>electric current</property>
+      <value Unit="A" UNIT="A" value="10">10</value>
+   </unit>
+   <unit Code="St" CODE="ST" isMetric="yes" class="cgs">
+      <name>Stokes</name>
+      <printSymbol>St</printSymbol>
+      <property>kinematic viscosity</property>
+      <value Unit="cm2/s" UNIT="CM2/S" value="1">1</value>
+   </unit>
+   <unit Code="Mx" CODE="MX" isMetric="yes" class="cgs">
+      <name>Maxwell</name>
+      <printSymbol>Mx</printSymbol>
+      <property>flux of magnetic induction</property>
+      <value Unit="Wb" UNIT="WB" value="1e-8">1 &#215; 10<sup>-8</sup>
+      </value>
+   </unit>
+   <unit Code="G" CODE="GS" isMetric="yes" class="cgs">
+      <name>Gauss</name>
+      <printSymbol>Gs</printSymbol>
+      <property>magnetic flux density</property>
+      <value Unit="T" UNIT="T" value="1e-4">1 &#215; 10<sup>-4</sup>
+      </value>
+   </unit>
+   <unit Code="Oe" CODE="OE" isMetric="yes" class="cgs">
+      <name>Oersted</name>
+      <printSymbol>Oe</printSymbol>
+      <property>magnetic field intensity</property>
+      <value Unit="/[pi].A/m" UNIT="/[PI].A/M" value="250">250</value>
+   </unit>
+   <unit Code="Gb" CODE="GB" isMetric="yes" class="cgs">
+      <name>Gilbert</name>
+      <printSymbol>Gb</printSymbol>
+      <property>magnetic tension</property>
+      <value Unit="Oe.cm" UNIT="OE.CM" value="1">1</value>
+   </unit>
+   <unit Code="sb" CODE="SB" isMetric="yes" class="cgs">
+      <name>stilb</name>
+      <printSymbol>sb</printSymbol>
+      <property>lum. intensity density</property>
+      <value Unit="cd/cm2" UNIT="CD/CM2" value="1">1</value>
+   </unit>
+   <unit Code="Lmb" CODE="LMB" isMetric="yes" class="cgs">
+      <name>Lambert</name>
+      <printSymbol>L</printSymbol>
+      <property>brightness</property>
+      <value Unit="cd/cm2/[pi]" UNIT="CD/CM2/[PI]" value="1">1</value>
+   </unit>
+   <unit Code="ph" CODE="PHT" isMetric="yes" class="cgs">
+      <name>phot</name>
+      <printSymbol>ph</printSymbol>
+      <property>illuminance</property>
+      <value Unit="lx" UNIT="LX" value="1e-4">1 &#215; 10<sup>-4</sup>
+      </value>
+   </unit>
+   <unit Code="Ci" CODE="CI" isMetric="yes" class="cgs">
+      <name>Curie</name>
+      <printSymbol>Ci</printSymbol>
+      <property>radioactivity</property>
+      <value Unit="Bq" UNIT="BQ" value="3.7e10">3.7 &#215; 10<sup>10</sup>
+      </value>
+   </unit>
+   <unit Code="R" CODE="ROE" isMetric="yes" class="cgs">
+      <name>Roentgen</name>
+      <printSymbol>R</printSymbol>
+      <property>ion dose</property>
+      <value Unit="C/kg" UNIT="C/KG" value="2.58e-4">2.58 &#215; 10<sup>-4</sup>
+      </value>
+   </unit>
+   <unit Code="RAD" CODE="[RAD]" isMetric="yes" class="cgs">
+      <name>radiation absorbed dose</name>
+      <printSymbol>RAD</printSymbol>
+      <property>energy dose</property>
+      <value Unit="erg/g" UNIT="ERG/G" value="100">100</value>
+   </unit>
+   <unit Code="REM" CODE="[REM]" isMetric="yes" class="cgs">
+      <name>radiation equivalent man</name>
+      <printSymbol>REM</printSymbol>
+      <property>dose equivalent</property>
+      <value Unit="RAD" UNIT="[RAD]" value="1">1</value>
+   </unit>
+   <unit Code="[in_i]" CODE="[IN_I]" isMetric="no" class="intcust">
+      <name>inch</name>
+      <printSymbol>in</printSymbol>
+      <property>length</property>
+      <value Unit="cm" UNIT="CM" value="254e-2">2.54</value>
+   </unit>
+   <unit Code="[ft_i]" CODE="[FT_I]" isMetric="no" class="intcust">
+      <name>foot</name>
+      <printSymbol>ft</printSymbol>
+      <property>length</property>
+      <value Unit="[in_i]" UNIT="[IN_I]" value="12">12</value>
+   </unit>
+   <unit Code="[yd_i]" CODE="[YD_I]" isMetric="no" class="intcust">
+      <name>yard</name>
+      <printSymbol>yd</printSymbol>
+      <property>length</property>
+      <value Unit="[ft_i]" UNIT="[FT_I]" value="3">3</value>
+   </unit>
+   <unit Code="[mi_i]" CODE="[MI_I]" isMetric="no" class="intcust">
+      <name>statute mile</name>
+      <printSymbol>mi</printSymbol>
+      <property>length</property>
+      <value Unit="[ft_i]" UNIT="[FT_I]" value="5280">5280</value>
+   </unit>
+   <unit Code="[fth_i]" CODE="[FTH_I]" isMetric="no" class="intcust">
+      <name>fathom</name>
+      <printSymbol>fth</printSymbol>
+      <property>depth of water</property>
+      <value Unit="[ft_i]" UNIT="[FT_I]" value="6">6</value>
+   </unit>
+   <unit Code="[nmi_i]" CODE="[NMI_I]" isMetric="no" class="intcust">
+      <name>nautical mile</name>
+      <printSymbol>n.mi</printSymbol>
+      <property>length</property>
+      <value Unit="m" UNIT="M" value="1852">1852</value>
+   </unit>
+   <unit Code="[kn_i]" CODE="[KN_I]" isMetric="no" class="intcust">
+      <name>knot</name>
+      <printSymbol>knot</printSymbol>
+      <property>velocity</property>
+      <value Unit="[nmi_i]/h" UNIT="[NMI_I]/H" value="1">1</value>
+   </unit>
+   <unit Code="[sin_i]" CODE="[SIN_I]" isMetric="no" class="intcust">
+      <name>square inch</name>
+      <property>area</property>
+      <value Unit="[in_i]2" UNIT="[IN_I]2" value="1">1</value>
+   </unit>
+   <unit Code="[sft_i]" CODE="[SFT_I]" isMetric="no" class="intcust">
+      <name>square foot</name>
+      <property>area</property>
+      <value Unit="[ft_i]2" UNIT="[FT_I]2" value="1">1</value>
+   </unit>
+   <unit Code="[syd_i]" CODE="[SYD_I]" isMetric="no" class="intcust">
+      <name>square yard</name>
+      <property>area</property>
+      <value Unit="[yd_i]2" UNIT="[YD_I]2" value="1">1</value>
+   </unit>
+   <unit Code="[cin_i]" CODE="[CIN_I]" isMetric="no" class="intcust">
+      <name>cubic inch</name>
+      <property>volume</property>
+      <value Unit="[in_i]3" UNIT="[IN_I]3" value="1">1</value>
+   </unit>
+   <unit Code="[cft_i]" CODE="[CFT_I]" isMetric="no" class="intcust">
+      <name>cubic foot</name>
+      <property>volume</property>
+      <value Unit="[ft_i]3" UNIT="[FT_I]3" value="1">1</value>
+   </unit>
+   <unit Code="[cyd_i]" CODE="[CYD_I]" isMetric="no" class="intcust">
+      <name>cubic yard</name>
+      <printSymbol>cu.yd</printSymbol>
+      <property>volume</property>
+      <value Unit="[yd_i]3" UNIT="[YD_I]3" value="1">1</value>
+   </unit>
+   <unit Code="[bf_i]" CODE="[BF_I]" isMetric="no" class="intcust">
+      <name>board foot</name>
+      <property>volume</property>
+      <value Unit="[in_i]3" UNIT="[IN_I]3" value="144">144</value>
+   </unit>
+   <unit Code="[cr_i]" CODE="[CR_I]" isMetric="no" class="intcust">
+      <name>cord</name>
+      <property>volume</property>
+      <value Unit="[ft_i]3" UNIT="[FT_I]3" value="128">128</value>
+   </unit>
+   <unit Code="[mil_i]" CODE="[MIL_I]" isMetric="no" class="intcust">
+      <name>mil</name>
+      <printSymbol>mil</printSymbol>
+      <property>length</property>
+      <value Unit="[in_i]" UNIT="[IN_I]" value="1e-3">1 &#215; 10<sup>-3</sup>
+      </value>
+   </unit>
+   <unit Code="[cml_i]" CODE="[CML_I]" isMetric="no" class="intcust">
+      <name>circular mil</name>
+      <printSymbol>circ.mil</printSymbol>
+      <property>area</property>
+      <value Unit="[pi]/4.[mil_i]2" UNIT="[PI]/4.[MIL_I]2" value="1">1</value>
+   </unit>
+   <unit Code="[hd_i]" CODE="[HD_I]" isMetric="no" class="intcust">
+      <name>hand</name>
+      <printSymbol>hd</printSymbol>
+      <property>height of horses</property>
+      <value Unit="[in_i]" UNIT="[IN_I]" value="4">4</value>
+   </unit>
+   <unit Code="[ft_us]" CODE="[FT_US]" isMetric="no" class="us-lengths">
+      <name>foot</name>
+      <printSymbol>ft<sub>us</sub>
+      </printSymbol>
+      <property>length</property>
+      <value Unit="m/3937" UNIT="M/3937" value="1200">1200</value>
+   </unit>
+   <unit Code="[yd_us]" CODE="[YD_US]" isMetric="no" class="us-lengths">
+      <name>yard</name>
+      <property>length</property>
+      <value Unit="[ft_us]" UNIT="[FT_US]" value="3">3</value>
+   </unit>
+   <unit Code="[in_us]" CODE="[IN_US]" isMetric="no" class="us-lengths">
+      <name>inch</name>
+      <property>length</property>
+      <value Unit="[ft_us]/12" UNIT="[FT_US]/12" value="1">1</value>
+   </unit>
+   <unit Code="[rd_us]" CODE="[RD_US]" isMetric="no" class="us-lengths">
+      <name>rod</name>
+      <property>length</property>
+      <value Unit="[ft_us]" UNIT="[FT_US]" value="16.5">16.5</value>
+   </unit>
+   <unit Code="[ch_us]" CODE="[CH_US]" isMetric="no" class="us-lengths">
+      <name>Gunter's chain</name>
+      <name>Surveyor's chain</name>
+      <property>length</property>
+      <value Unit="[rd_us]" UNIT="[RD_US]" value="4">4</value>
+   </unit>
+   <unit Code="[lk_us]" CODE="[LK_US]" isMetric="no" class="us-lengths">
+      <name>link for Gunter's chain</name>
+      <property>length</property>
+      <value Unit="[ch_us]/100" UNIT="[CH_US]/100" value="1">1</value>
+   </unit>
+   <unit Code="[rch_us]" CODE="[RCH_US]" isMetric="no" class="us-lengths">
+      <name>Ramden's chain</name>
+      <name>Engineer's chain</name>
+      <property>length</property>
+      <value Unit="[ft_us]" UNIT="[FT_US]" value="100">100</value>
+   </unit>
+   <unit Code="[rlk_us]" CODE="[RLK_US]" isMetric="no" class="us-lengths">
+      <name>link for Ramden's chain</name>
+      <property>length</property>
+      <value Unit="[rch_us]/100" UNIT="[RCH_US]/100" value="1">1</value>
+   </unit>
+   <unit Code="[fth_us]" CODE="[FTH_US]" isMetric="no" class="us-lengths">
+      <name>fathom</name>
+      <property>length</property>
+      <value Unit="[ft_us]" UNIT="[FT_US]" value="6">6</value>
+   </unit>
+   <unit Code="[fur_us]" CODE="[FUR_US]" isMetric="no" class="us-lengths">
+      <name>furlong</name>
+      <property>length</property>
+      <value Unit="[rd_us]" UNIT="[RD_US]" value="40">40</value>
+   </unit>
+   <unit Code="[mi_us]" CODE="[MI_US]" isMetric="no" class="us-lengths">
+      <name>mile</name>
+      <property>length</property>
+      <value Unit="[fur_us]" UNIT="[FUR_US]" value="8">8</value>
+   </unit>
+   <unit Code="[acr_us]" CODE="[ACR_US]" isMetric="no" class="us-lengths">
+      <name>acre</name>
+      <property>area</property>
+      <value Unit="[rd_us]2" UNIT="[RD_US]2" value="160">160</value>
+   </unit>
+   <unit Code="[srd_us]" CODE="[SRD_US]" isMetric="no" class="us-lengths">
+      <name>square rod</name>
+      <property>area</property>
+      <value Unit="[rd_us]2" UNIT="[RD_US]2" value="1">1</value>
+   </unit>
+   <unit Code="[smi_us]" CODE="[SMI_US]" isMetric="no" class="us-lengths">
+      <name>square mile</name>
+      <property>area</property>
+      <value Unit="[mi_us]2" UNIT="[MI_US]2" value="1">1</value>
+   </unit>
+   <unit Code="[sct]" CODE="[SCT]" isMetric="no" class="us-lengths">
+      <name>section</name>
+      <property>area</property>
+      <value Unit="[mi_us]2" UNIT="[MI_US]2" value="1">1</value>
+   </unit>
+   <unit Code="[twp]" CODE="[TWP]" isMetric="no" class="us-lengths">
+      <name>township</name>
+      <property>area</property>
+      <value Unit="[sct]" UNIT="[SCT]" value="36">36</value>
+   </unit>
+   <unit Code="[mil_us]" CODE="[MIL_US]" isMetric="no" class="us-lengths">
+      <name>mil</name>
+      <property>length</property>
+      <value Unit="[in_us]" UNIT="[IN_US]" value="1e-3">1 &#215; 10<sup>-3</sup>
+      </value>
+   </unit>
+   <unit Code="[in_br]" CODE="[IN_BR]" isMetric="no" class="brit-length">
+      <name>inch</name>
+      <property>length</property>
+      <value Unit="cm" UNIT="CM" value="2.539998">2.539998</value>
+   </unit>
+   <unit Code="[ft_br]" CODE="[FT_BR]" isMetric="no" class="brit-length">
+      <name>foot</name>
+      <property>length</property>
+      <value Unit="[in_br]" UNIT="[IN_BR]" value="12">12</value>
+   </unit>
+   <unit Code="[rd_br]" CODE="[RD_BR]" isMetric="no" class="brit-length">
+      <name>rod</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="16.5">16.5</value>
+   </unit>
+   <unit Code="[ch_br]" CODE="[CH_BR]" isMetric="no" class="brit-length">
+      <name>Gunter's chain</name>
+      <property>length</property>
+      <value Unit="[rd_br]" UNIT="[RD_BR]" value="4">4</value>
+   </unit>
+   <unit Code="[lk_br]" CODE="[LK_BR]" isMetric="no" class="brit-length">
+      <name>link for Gunter's chain</name>
+      <property>length</property>
+      <value Unit="[ch_br]/100" UNIT="[CH_BR]/100" value="1">1</value>
+   </unit>
+   <unit Code="[fth_br]" CODE="[FTH_BR]" isMetric="no" class="brit-length">
+      <name>fathom</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="6">6</value>
+   </unit>
+   <unit Code="[pc_br]" CODE="[PC_BR]" isMetric="no" class="brit-length">
+      <name>pace</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="2.5">2.5</value>
+   </unit>
+   <unit Code="[yd_br]" CODE="[YD_BR]" isMetric="no" class="brit-length">
+      <name>yard</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="3">3</value>
+   </unit>
+   <unit Code="[mi_br]" CODE="[MI_BR]" isMetric="no" class="brit-length">
+      <name>mile</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="5280">5280</value>
+   </unit>
+   <unit Code="[nmi_br]" CODE="[NMI_BR]" isMetric="no" class="brit-length">
+      <name>nautical mile</name>
+      <property>length</property>
+      <value Unit="[ft_br]" UNIT="[FT_BR]" value="6080">6080</value>
+   </unit>
+   <unit Code="[kn_br]" CODE="[KN_BR]" isMetric="no" class="brit-length">
+      <name>knot</name>
+      <property>velocity</property>
+      <value Unit="[nmi_br]/h" UNIT="[NMI_BR]/H" value="1">1</value>
+   </unit>
+   <unit Code="[acr_br]" CODE="[ACR_BR]" isMetric="no" class="brit-length">
+      <name>acre</name>
+      <property>area</property>
+      <value Unit="[yd_br]2" UNIT="[YD_BR]2" value="4840">4840</value>
+   </unit>
+   <unit Code="[gal_us]" CODE="[GAL_US]" isMetric="no" class="us-volumes">
+      <name>Queen&#160;Anne's wine gallon</name>
+      <property>fluid volume</property>
+      <value Unit="[in_i]3" UNIT="[IN_I]3" value="231">231</value>
+   </unit>
+   <unit Code="[bbl_us]" CODE="[BBL_US]" isMetric="no" class="us-volumes">
+      <name>barrel</name>
+      <property>fluid volume</property>
+      <value Unit="[gal_us]" UNIT="[GAL_US]" value="42">42</value>
+   </unit>
+   <unit Code="[qt_us]" CODE="[QT_US]" isMetric="no" class="us-volumes">
+      <name>quart</name>
+      <property>fluid volume</property>
+      <value Unit="[gal_us]/4" UNIT="[GAL_US]/4" value="1">1</value>
+   </unit>
+   <unit Code="[pt_us]" CODE="[PT_US]" isMetric="no" class="us-volumes">
+      <name>pint</name>
+      <property>fluid volume</property>
+      <value Unit="[qt_us]/2" UNIT="[QT_US]/2" value="1">1</value>
+   </unit>
+   <unit Code="[gil_us]" CODE="[GIL_US]" isMetric="no" class="us-volumes">
+      <name>gill</name>
+      <property>fluid volume</property>
+      <value Unit="[pt_us]/4" UNIT="[PT_US]/4" value="1">1</value>
+   </unit>
+   <unit Code="[foz_us]" CODE="[FOZ_US]" isMetric="no" class="us-volumes">
+      <name>fluid ounce</name>
+      <printSymbol>oz fl</printSymbol>
+      <property>fluid volume</property>
+      <value Unit="[gil_us]/4" UNIT="[GIL_US]/4" value="1">1</value>
+   </unit>
+   <unit Code="[fdr_us]" CODE="[FDR_US]" isMetric="no" class="us-volumes">
+      <name>fluid dram</name>
+      <property>fluid volume</property>
+      <value Unit="[foz_us]/8" UNIT="[FOZ_US]/8" value="1">1</value>
+   </unit>
+   <unit Code="[min_us]" CODE="[MIN_US]" isMetric="no" class="us-volumes">
+      <name>minim</name>
+      <property>fluid volume</property>
+      <value Unit="[fdr_us]/60" UNIT="[FDR_US]/60" value="1">1</value>
+   </unit>
+   <unit Code="[crd_us]" CODE="[CRD_US]" isMetric="no" class="us-volumes">
+      <name>cord</name>
+      <property>fluid volume</property>
+      <value Unit="[ft_i]3" UNIT="[FT_I]3" value="128">128</value>
+   </unit>
+   <unit Code="[bu_us]" CODE="[BU_US]" isMetric="no" class="us-volumes">
+      <name>bushel</name>
+      <property>dry volume</property>
+      <value Unit="[in_i]3" UNIT="[IN_I]3" value="2150.42">2150.42</value>
+   </unit>
+   <unit Code="[gal_wi]" CODE="[GAL_WI]" isMetric="no" class="us-volumes">
+      <name>historical winchester gallon</name>
+      <property>dry volume</property>
+      <value Unit="[bu_us]/8" UNIT="[BU_US]/8" value="1">1</value>
+   </unit>
+   <unit Code="[pk_us]" CODE="[PK_US]" isMetric="no" class="us-volumes">
+      <name>peck</name>
+      <property>dry volume</property>
+      <value Unit="[bu_us]/4" UNIT="[BU_US]/4" value="1">1</value>
+   </unit>
+   <unit Code="[dqt_us]" CODE="[DQT_US]" isMetric="no" class="us-volumes">
+      <name>dry quart</name>
+      <property>dry volume</property>
+      <value Unit="[pk_us]/8" UNIT="[PK_US]/8" value="1">1</value>
+   </unit>
+   <unit Code="[dpt_us]" CODE="[DPT_US]" isMetric="no" class="us-volumes">
+      <name>dry pint</name>
+      <property>dry volume</property>
+      <value Unit="[dqt_us]/2" UNIT="[DQT_US]/2" value="1">1</value>
+   </unit>
+   <unit Code="[tbs_us]" CODE="[TBS_US]" isMetric="no" class="us-volumes">
+      <name>tablespoon</name>
+      <property>volume</property>
+      <value Unit="[foz_us]/2" UNIT="[FOZ_US]/2" value="1">1</value>
+   </unit>
+   <unit Code="[tsp_us]" CODE="[TSP_US]" isMetric="no" class="us-volumes">
+      <name>teaspoon</name>
+      <property>volume</property>
+      <value Unit="[tbs_us]/3" UNIT="[TBS_US]/3" value="1">1</value>
+   </unit>
+   <unit Code="[cup_us]" CODE="[CUP_US]" isMetric="no" class="us-volumes">
+      <name>cup</name>
+      <property>volume</property>
+      <value Unit="[tbs_us]" UNIT="[TBS_US]" value="16">16</value>
+   </unit>
+   <unit Code="[gal_br]" CODE="[GAL_BR]" isMetric="no" class="brit-volumes">
+      <name>gallon</name>
+      <property>volume</property>
+      <value Unit="l" UNIT="L" value="4.54609">4.54609</value>
+   </unit>
+   <unit Code="[pk_br]" CODE="[PK_BR]" isMetric="no" class="brit-volumes">
+      <name>peck</name>
+      <property>volume</property>
+      <value Unit="[gal_br]" UNIT="[GAL_BR]" value="2">2</value>
+   </unit>
+   <unit Code="[bu_br]" CODE="[BU_BR]" isMetric="no" class="brit-volumes">
+      <name>bushel</name>
+      <property>volume</property>
+      <value Unit="[pk_br]" UNIT="[PK_BR]" value="4">4</value>
+   </unit>
+   <unit Code="[qt_br]" CODE="[QT_BR]" isMetric="no" class="brit-volumes">
+      <name>quart</name>
+      <property>volume</property>
+      <value Unit="[gal_br]/4" UNIT="[GAL_BR]/4" value="1">1</value>
+   </unit>
+   <unit Code="[pt_br]" CODE="[PT_BR]" isMetric="no" class="brit-volumes">
+      <name>pint</name>
+      <property>volume</property>
+      <value Unit="[qt_br]/2" UNIT="[QT_BR]/2" value="1">1</value>
+   </unit>
+   <unit Code="[gil_br]" CODE="[GIL_BR]" isMetric="no" class="brit-volumes">
+      <name>gill</name>
+      <property>volume</property>
+      <value Unit="[pt_br]/4" UNIT="[PT_BR]/4" value="1">1</value>
+   </unit>
+   <unit Code="[foz_br]" CODE="[FOZ_BR]" isMetric="no" class="brit-volumes">
+      <name>fluid ounce</name>
+      <property>volume</property>
+      <value Unit="[gil_br]/5" UNIT="[GIL_BR]/5" value="1">1</value>
+   </unit>
+   <unit Code="[fdr_br]" CODE="[FDR_BR]" isMetric="no" class="brit-volumes">
+      <name>fluid dram</name>
+      <property>volume</property>
+      <value Unit="[foz_br]/8" UNIT="[FOZ_BR]/8" value="1">1</value>
+   </unit>
+   <unit Code="[min_br]" CODE="[MIN_BR]" isMetric="no" class="brit-volumes">
+      <name>minim</name>
+      <property>volume</property>
+      <value Unit="[fdr_br]/60" UNIT="[FDR_BR]/60" value="1">1</value>
+   </unit>
+   <unit Code="[gr]" CODE="[GR]" isMetric="no" class="avoirdupois">
+      <name>grain</name>
+      <property>mass</property>
+      <value Unit="mg" UNIT="MG" value="64.79891">64.79891</value>
+   </unit>
+   <unit Code="[lb_av]" CODE="[LB_AV]" isMetric="no" class="avoirdupois">
+      <name>pound</name>
+      <printSymbol>lb</printSymbol>
+      <property>mass</property>
+      <value Unit="[gr]" UNIT="[GR]" value="7000">7000</value>
+   </unit>
+   <unit Code="[oz_av]" CODE="[OZ_AV]" isMetric="no" class="avoirdupois">
+      <name>ounce</name>
+      <printSymbol>oz</printSymbol>
+      <property>mass</property>
+      <value Unit="[lb_av]/16" UNIT="[LB_AV]/16" value="1">1</value>
+   </unit>
+   <unit Code="[dr_av]" CODE="[DR_AV]" isMetric="no" class="avoirdupois">
+      <name>dram</name>
+      <property>mass</property>
+      <value Unit="[oz_av]/16" UNIT="[OZ_AV]/16" value="1">1</value>
+   </unit>
+   <unit Code="[scwt_av]" CODE="[SCWT_AV]" isMetric="no" class="avoirdupois">
+      <name>short hundredweight</name>
+      <name>U.S. hundredweight</name>
+      <property>mass</property>
+      <value Unit="[lb_av]" UNIT="[LB_AV]" value="100">100</value>
+   </unit>
+   <unit Code="[lcwt_av]" CODE="[LCWT_AV]" isMetric="no" class="avoirdupois">
+      <name>long hunderdweight</name>
+      <name>British hundredweight</name>
+      <property>mass</property>
+      <value Unit="[lb_av]" UNIT="[LB_AV]" value="112">112</value>
+   </unit>
+   <unit Code="[ston_av]" CODE="[STON_AV]" isMetric="no" class="avoirdupois">
+      <name>short ton</name>
+      <name>U.S. ton</name>
+      <property>mass</property>
+      <value Unit="[scwt_av]" UNIT="[SCWT_AV]" value="20">20</value>
+   </unit>
+   <unit Code="[lton_av]" CODE="[LTON_AV]" isMetric="no" class="avoirdupois">
+      <name>long ton</name>
+      <name>British ton</name>
+      <property>mass</property>
+      <value Unit="[lcwt_av]" UNIT="[LCWT_AV]" value="20">20</value>
+   </unit>
+   <unit Code="[stone_av]" CODE="[STONE_AV]" isMetric="no" class="avoirdupois">
+      <name>stone</name>
+      <name>British stone</name>
+      <property>mass</property>
+      <value Unit="[lb_av]" UNIT="[LB_AV]" value="14">14</value>
+   </unit>
+   <unit Code="[pwt_tr]" CODE="[PWT_TR]" isMetric="no" class="troy">
+      <name>pennyweight</name>
+      <property>mass</property>
+      <value Unit="[gr]" UNIT="[GR]" value="24">24</value>
+   </unit>
+   <unit Code="[oz_tr]" CODE="[OZ_TR]" isMetric="no" class="troy">
+      <name>ounce</name>
+      <property>mass</property>
+      <value Unit="[pwt_tr]" UNIT="[PWT_TR]" value="20">20</value>
+   </unit>
+   <unit Code="[lb_tr]" CODE="[LB_TR]" isMetric="no" class="troy">
+      <name>pound</name>
+      <property>mass</property>
+      <value Unit="[oz_tr]" UNIT="[OZ_TR]" value="12">12</value>
+   </unit>
+   <unit Code="[sc_ap]" CODE="[SC_AP]" isMetric="no" class="apoth">
+      <name>scruple</name>
+      <property>mass</property>
+      <value Unit="[gr]" UNIT="[GR]" value="20">20</value>
+   </unit>
+   <unit Code="[dr_ap]" CODE="[DR_AP]" isMetric="no" class="apoth">
+      <name>dram</name>
+      <name>drachm</name>
+      <property>mass</property>
+      <value Unit="[sc_ap]" UNIT="[SC_AP]" value="3">3</value>
+   </unit>
+   <unit Code="[oz_ap]" CODE="[OZ_AP]" isMetric="no" class="apoth">
+      <name>ounce</name>
+      <property>mass</property>
+      <value Unit="[dr_ap]" UNIT="[DR_AP]" value="8">8</value>
+   </unit>
+   <unit Code="[lb_ap]" CODE="[LB_AP]" isMetric="no" class="apoth">
+      <name>pound</name>
+      <property>mass</property>
+      <value Unit="[oz_ap]" UNIT="[OZ_AP]" value="12">12</value>
+   </unit>
+   <unit Code="[lne]" CODE="[LNE]" isMetric="no" class="typeset">
+      <name>line</name>
+      <property>length</property>
+      <value Unit="[in_i]/12" UNIT="[IN_I]/12" value="1">1</value>
+   </unit>
+   <unit Code="[pnt]" CODE="[PNT]" isMetric="no" class="typeset">
+      <name>point</name>
+      <property>length</property>
+      <value Unit="[lne]/6" UNIT="[LNE]/6" value="1">1</value>
+   </unit>
+   <unit Code="[pca]" CODE="[PCA]" isMetric="no" class="typeset">
+      <name>pica</name>
+      <property>length</property>
+      <value Unit="[pnt]" UNIT="[PNT]" value="12">12</value>
+   </unit>
+   <unit Code="[pnt_pr]" CODE="[PNT_PR]" isMetric="no" class="typeset">
+      <name>Printer's point</name>
+      <property>length</property>
+      <value Unit="[in_i]" UNIT="[IN_I]" value="0.013837">0.013837</value>
+   </unit>
+   <unit Code="[pca_pr]" CODE="[PCA_PR]" isMetric="no" class="typeset">
+      <name>Printer's pica</name>
+      <property>length</property>
+      <value Unit="[pnt_pr]" UNIT="[PNT_PR]" value="12">12</value>
+   </unit>
+   <unit Code="[pied]" CODE="[PIED]" isMetric="no" class="typeset">
+      <name>pied</name>
+      <name>French foot</name>
+      <property>length</property>
+      <value Unit="cm" UNIT="CM" value="32.48">32.48</value>
+   </unit>
+   <unit Code="[pouce]" CODE="[POUCE]" isMetric="no" class="typeset">
+      <name>pouce</name>
+      <name>French inch</name>
+      <property>length</property>
+      <value Unit="[pied]/12" UNIT="[PIED]/12" value="1">1</value>
+   </unit>
+   <unit Code="[ligne]" CODE="[LIGNE]" isMetric="no" class="typeset">
+      <name>ligne</name>
+      <name>French line</name>
+      <property>length</property>
+      <value Unit="[pouce]/12" UNIT="[POUCE]/12" value="1">1</value>
+   </unit>
+   <unit Code="[didot]" CODE="[DIDOT]" isMetric="no" class="typeset">
+      <name>didot</name>
+      <name>Didot's point</name>
+      <property>length</property>
+      <value Unit="[ligne]/6" UNIT="[LIGNE]/6" value="1">1</value>
+   </unit>
+   <unit Code="[cicero]" CODE="[CICERO]" isMetric="no" class="typeset">
+      <name>cicero</name>
+      <name>Didot's pica</name>
+      <property>length</property>
+      <value Unit="[didot]" UNIT="[DIDOT]" value="12">12</value>
+   </unit>
+   <unit Code="[degF]" CODE="[DEGF]" isMetric="no" isSpecial="yes" class="heat">
+      <name>degree Fahrenheit</name>
+      <printSymbol>&#176;F</printSymbol>
+      <property>temperature</property>
+      <value Unit="degf(5 K/9)" UNIT="DEGF(5 K/9)">
+         <function name="degF" value="5" Unit="K/9"/>
+      </value>
+   </unit>
+   <unit Code="cal_[15]" CODE="CAL_[15]" isMetric="yes" class="heat">
+      <name>calorie at 15&#160;&#176;C</name>
+      <printSymbol>cal<sub>15&#176;C</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="J" UNIT="J" value="4.18580">4.18580</value>
+   </unit>
+   <unit Code="cal_[20]" CODE="CAL_[20]" isMetric="yes" class="heat">
+      <name>calorie at 20&#160;&#176;C</name>
+      <printSymbol>cal<sub>20&#176;C</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="J" UNIT="J" value="4.18190">4.18190</value>
+   </unit>
+   <unit Code="cal_m" CODE="CAL_M" isMetric="yes" class="heat">
+      <name>mean calorie</name>
+      <printSymbol>cal<sub>m</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="J" UNIT="J" value="4.19002">4.19002</value>
+   </unit>
+   <unit Code="cal_IT" CODE="CAL_IT" isMetric="yes" class="heat">
+      <name>international table calorie</name>
+      <printSymbol>cal<sub>IT</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="J" UNIT="J" value="4.1868">4.1868</value>
+   </unit>
+   <unit Code="cal_th" CODE="CAL_TH" isMetric="yes" class="heat">
+      <name>thermochemical calorie</name>
+      <printSymbol>cal<sub>th</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="J" UNIT="J" value="4.184">4.184</value>
+   </unit>
+   <unit Code="cal" CODE="CAL" isMetric="yes" class="heat">
+      <name>calorie</name>
+      <printSymbol>cal</printSymbol>
+      <property>energy</property>
+      <value Unit="cal_th" UNIT="CAL_TH" value="1">1</value>
+   </unit>
+   <unit Code="[Cal]" CODE="[CAL]" isMetric="no" class="heat">
+      <name>nutrition label Calories</name>
+      <printSymbol>Cal</printSymbol>
+      <property>energy</property>
+      <value Unit="kcal_th" UNIT="KCAL_TH" value="1">1</value>
+   </unit>
+   <unit Code="[Btu_39]" CODE="[BTU_39]" isMetric="no" class="heat">
+      <name>British thermal unit at 39&#160;&#176;F</name>
+      <printSymbol>Btu<sub>39&#176;F</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.05967">1.05967</value>
+   </unit>
+   <unit Code="[Btu_59]" CODE="[BTU_59]" isMetric="no" class="heat">
+      <name>British thermal unit at 59&#160;&#176;F</name>
+      <printSymbol>Btu<sub>59&#176;F</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.05480">1.05480</value>
+   </unit>
+   <unit Code="[Btu_60]" CODE="[BTU_60]" isMetric="no" class="heat">
+      <name>British thermal unit at 60&#160;&#176;F</name>
+      <printSymbol>Btu<sub>60&#176;F</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.05468">1.05468</value>
+   </unit>
+   <unit Code="[Btu_m]" CODE="[BTU_M]" isMetric="no" class="heat">
+      <name>mean British thermal unit</name>
+      <printSymbol>Btu<sub>m</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.05587">1.05587</value>
+   </unit>
+   <unit Code="[Btu_IT]" CODE="[BTU_IT]" isMetric="no" class="heat">
+      <name>international table British thermal unit</name>
+      <printSymbol>Btu<sub>IT</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.05505585262">1.05505585262</value>
+   </unit>
+   <unit Code="[Btu_th]" CODE="[BTU_TH]" isMetric="no" class="heat">
+      <name>thermochemical British thermal unit</name>
+      <printSymbol>Btu<sub>th</sub>
+      </printSymbol>
+      <property>energy</property>
+      <value Unit="kJ" UNIT="kJ" value="1.054350">1.054350</value>
+   </unit>
+   <unit Code="[Btu]" CODE="[BTU]" isMetric="no" class="heat">
+      <name>British thermal unit</name>
+      <printSymbol>btu</printSymbol>
+      <property>energy</property>
+      <value Unit="[Btu_th]" UNIT="[BTU_TH]" value="1">1</value>
+   </unit>
+   <unit Code="[HP]" CODE="[HP]" isMetric="no" class="heat">
+      <name>horsepower</name>
+      <property>power</property>
+      <value Unit="[ft_i].[lbf_av]/s" UNIT="[FT_I].[LBF_AV]/S" value="550">550</value>
+   </unit>
+   <unit Code="m[H2O]" CODE="M[H2O]" isMetric="yes" class="clinical">
+      <name>meter of water column</name>
+      <printSymbol>m&#160;H<sub>
+            <r>2</r>
+         </sub>O</printSymbol>
+      <property>pressure</property>
+      <value Unit="kPa" UNIT="KPAL" value="9.80665">9.80665</value>
+   </unit>
+   <unit Code="m[Hg]" CODE="M[HG]" isMetric="yes" class="clinical">
+      <name>meter of mercury column</name>
+      <printSymbol>m&#160;Hg</printSymbol>
+      <property>pressure</property>
+      <value Unit="kPa" UNIT="KPAL" value="133.3220">133.3220</value>
+   </unit>
+   <unit Code="[in_i'H2O]" CODE="[IN_I'H2O]" isMetric="no" class="clinical">
+      <name>inch of water column</name>
+      <printSymbol>in&#160;H<sub>
+            <r>2</r>
+         </sub>O</printSymbol>
+      <property>pressure</property>
+      <value Unit="m[H2O].[in_i]/m" UNIT="M[H2O].[IN_I]/M" value="1">1</value>
+   </unit>
+   <unit Code="[in_i'Hg]" CODE="[IN_i'HG]" isMetric="no" class="clinical">
+      <name>inch of mercury column</name>
+      <printSymbol>in&#160;Hg</printSymbol>
+      <property>pressure</property>
+      <value Unit="m[Hg].[in_i]/m" UNIT="M[HG].[IN_I]/M" value="1">1</value>
+   </unit>
+   <unit Code="[PRU]" CODE="[PRU]" isMetric="no" class="clinical">
+      <name>peripheral vascular resistance unit</name>
+      <printSymbol>P.R.U.</printSymbol>
+      <property>fluid resistance</property>
+      <value Unit="mm[Hg].s/ml" UNIT="MM[HG].S/ML" value="1">1</value>
+   </unit>
+   <unit Code="[wood'U]" CODE="[WOOD'U]" isMetric="no" class="clinical">
+      <name>Wood unit</name>
+      <printSymbol>Wood U.</printSymbol>
+      <property>fluid resistance</property>
+      <value Unit="mm[Hg].min/L" UNIT="MM[HG].MIN/L" value="1">1</value>
+   </unit>
+   <unit Code="[diop]" CODE="[DIOP]" isMetric="no" class="clinical">
+      <name>diopter</name>
+      <printSymbol>dpt</printSymbol>
+      <property>refraction of a lens</property>
+      <value Unit="/m" UNIT="/M" value="1">1</value>
+   </unit>
+   <unit Code="[p'diop]" CODE="[P'DIOP]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>prism diopter</name>
+      <printSymbol>PD</printSymbol>
+      <property>refraction of a prism</property>
+      <value Unit="100tan(1 rad)" UNIT="100TAN(1 RAD)">
+         <function name="tanTimes100" value="1" Unit="deg"/>
+      </value>
+   </unit>
+   <unit Code="%[slope]" CODE="%[SLOPE]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>percent of slope</name>
+      <printSymbol>%</printSymbol>
+      <property>slope</property>
+      <value Unit="100tan(1 rad)" UNIT="100TAN(1 RAD)">
+         <function name="100tan" value="1" Unit="deg"/>
+      </value>
+   </unit>
+   <unit Code="[mesh_i]" CODE="[MESH_I]" isMetric="no" class="clinical">
+      <name>mesh</name>
+      <property>lineic number</property>
+      <value Unit="/[in_i]" UNIT="/[IN_I]" value="1">1</value>
+   </unit>
+   <unit Code="[Ch]" CODE="[CH]" isMetric="no" class="clinical">
+      <name>Charri&#232;re</name>
+      <name>french</name>
+      <printSymbol>Ch</printSymbol>
+      <property>gauge of catheters</property>
+      <value Unit="mm/[pi]" UNIT="MM/[PI]" value="1">1</value>
+   </unit>
+   <unit Code="[drp]" CODE="[DRP]" isMetric="no" class="clinical">
+      <name>drop</name>
+      <printSymbol>drp</printSymbol>
+      <property>volume</property>
+      <value Unit="ml/12" UNIT="ML/12" value="1">1</value>
+   </unit>
+   <unit Code="[hnsf'U]" CODE="[HNSF'U]" isMetric="no" class="clinical">
+      <name>Hounsfield unit</name>
+      <printSymbol>HF</printSymbol>
+      <property>x-ray attenuation</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[MET]" CODE="[MET]" isMetric="no" class="clinical">
+      <name>metabolic equivalent</name>
+      <printSymbol>MET</printSymbol>
+      <property>metabolic cost of physical activity</property>
+      <value Unit="mL/min/kg" UNIT="ML/MIN/KG" value="3.5">3.5</value>
+   </unit>
+   <unit Code="[hp'_X]" CODE="[HP'_X]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>homeopathic potency of decimal series (retired)</name>
+      <printSymbol>X</printSymbol>
+      <property>homeopathic potency (retired)</property>
+      <value Unit="hpX(1 1)" UNIT="HPX(1 1)">
+         <function name="hpX" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="[hp'_C]" CODE="[HP'_C]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>homeopathic potency of centesimal series (retired)</name>
+      <printSymbol>C</printSymbol>
+      <property>homeopathic potency (retired)</property>
+      <value Unit="hpC(1 1)" UNIT="HPC(1 1)">
+         <function name="hpC" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="[hp'_M]" CODE="[HP'_M]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>homeopathic potency of millesimal series (retired)</name>
+      <printSymbol>M</printSymbol>
+      <property>homeopathic potency (retired)</property>
+      <value Unit="hpM(1 1)" UNIT="HPM(1 1)">
+         <function name="hpM" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="[hp'_Q]" CODE="[HP'_Q]" isMetric="no" isSpecial="yes" class="clinical">
+      <name>homeopathic potency of quintamillesimal series (retired)</name>
+      <printSymbol>Q</printSymbol>
+      <property>homeopathic potency (retired)</property>
+      <value Unit="hpQ(1 1)" UNIT="HPQ(1 1)">
+         <function name="hpQ" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="[hp_X]" CODE="[HP_X]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of decimal hahnemannian series</name>
+      <printSymbol>X</printSymbol>
+      <property>homeopathic potency (Hahnemann)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[hp_C]" CODE="[HP_C]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of centesimal hahnemannian series</name>
+      <printSymbol>C</printSymbol>
+      <property>homeopathic potency (Hahnemann)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[hp_M]" CODE="[HP_M]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of millesimal hahnemannian series</name>
+      <printSymbol>M</printSymbol>
+      <property>homeopathic potency (Hahnemann)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[hp_Q]" CODE="[HP_Q]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of quintamillesimal hahnemannian series</name>
+      <printSymbol>Q</printSymbol>
+      <property>homeopathic potency (Hahnemann)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[kp_X]" CODE="[KP_X]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of decimal korsakovian series</name>
+      <printSymbol>X</printSymbol>
+      <property>homeopathic potency (Korsakov)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[kp_C]" CODE="[KP_C]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of centesimal korsakovian series</name>
+      <printSymbol>C</printSymbol>
+      <property>homeopathic potency (Korsakov)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[kp_M]" CODE="[KP_M]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of millesimal korsakovian series</name>
+      <printSymbol>M</printSymbol>
+      <property>homeopathic potency (Korsakov)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[kp_Q]" CODE="[KP_Q]" isMetric="no" isArbitrary="yes" class="clinical">
+      <name>homeopathic potency of quintamillesimal korsakovian series</name>
+      <printSymbol>Q</printSymbol>
+      <property>homeopathic potency (Korsakov)</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="eq" CODE="EQ" isMetric="yes" class="chemical">
+      <name>equivalents</name>
+      <printSymbol>eq</printSymbol>
+      <property>amount of substance</property>
+      <value Unit="mol" UNIT="MOL" value="1">1</value>
+   </unit>
+   <unit Code="osm" CODE="OSM" isMetric="yes" class="chemical">
+      <name>osmole</name>
+      <printSymbol>osm</printSymbol>
+      <property>amount of substance (dissolved particles)</property>
+      <value Unit="mol" UNIT="MOL" value="1">1</value>
+   </unit>
+   <unit Code="[pH]" CODE="[PH]" isMetric="no" isSpecial="yes" class="chemical">
+      <name>pH</name>
+      <printSymbol>pH</printSymbol>
+      <property>acidity</property>
+      <value Unit="pH(1 mol/l)" UNIT="PH(1 MOL/L)">
+         <function name="pH" value="1" Unit="mol/l"/>
+      </value>
+   </unit>
+   <unit Code="g%" CODE="G%" isMetric="yes" class="chemical">
+      <name>gram percent</name>
+      <printSymbol>g%</printSymbol>
+      <property>mass concentration</property>
+      <value Unit="g/dl" UNIT="G/DL" value="1">1</value>
+   </unit>
+   <unit Code="[S]" CODE="[S]" isMetric="no" class="chemical">
+      <name>Svedberg unit</name>
+      <printSymbol>S</printSymbol>
+      <property>sedimentation coefficient</property>
+      <value Unit="10*-13.s" UNIT="10*-13.S" value="1">1</value>
+   </unit>
+   <unit Code="[HPF]" CODE="[HPF]" isMetric="no" class="chemical">
+      <name>high power field</name>
+      <printSymbol>HPF</printSymbol>
+      <property>view area in microscope</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[LPF]" CODE="[LPF]" isMetric="no" class="chemical">
+      <name>low power field</name>
+      <printSymbol>LPF</printSymbol>
+      <property>view area in microscope</property>
+      <value Unit="1" UNIT="1" value="100">100</value>
+   </unit>
+   <unit Code="kat" CODE="KAT" isMetric="yes" class="chemical">
+      <name>katal</name>
+      <printSymbol>kat</printSymbol>
+      <property>catalytic activity</property>
+      <value Unit="mol/s" UNIT="MOL/S" value="1">1</value>
+   </unit>
+   <unit Code="U" CODE="U" isMetric="yes" class="chemical">
+      <name>Unit</name>
+      <printSymbol>U</printSymbol>
+      <property>catalytic activity</property>
+      <value Unit="umol/min" UNIT="UMOL/MIN" value="1">1</value>
+   </unit>
+   <unit Code="[iU]" CODE="[IU]" isMetric="yes" isArbitrary="yes" class="chemical">
+      <name>international unit</name>
+      <printSymbol>IU</printSymbol>
+      <property>arbitrary</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[IU]" CODE="[IU]" isMetric="yes" isArbitrary="yes" class="chemical">
+      <name>international unit</name>
+      <printSymbol>i.U.</printSymbol>
+      <property>arbitrary</property>
+      <value Unit="[iU]" UNIT="[IU]" value="1">1</value>
+   </unit>
+   <unit Code="[arb'U]" CODE="[ARB'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>arbitary unit</name>
+      <printSymbol>arb. U</printSymbol>
+      <property>arbitrary</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[USP'U]" CODE="[USP'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>United States Pharmacopeia unit</name>
+      <printSymbol>U.S.P.</printSymbol>
+      <property>arbitrary</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[GPL'U]" CODE="[GPL'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>GPL unit</name>
+      <property>biologic activity of anticardiolipin IgG</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[MPL'U]" CODE="[MPL'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>MPL unit</name>
+      <property>biologic activity of anticardiolipin IgM</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[APL'U]" CODE="[APL'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>APL unit</name>
+      <property>biologic activity of anticardiolipin IgA</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[beth'U]" CODE="[BETH'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>Bethesda unit</name>
+      <property>biologic activity of factor VIII inhibitor</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[todd'U]" CODE="[TODD'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>Todd unit</name>
+      <property>biologic activity antistreptolysin O</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[dye'U]" CODE="[DYE'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>Dye unit</name>
+      <property>biologic activity of amylase</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[smgy'U]" CODE="[SMGY'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>Somogyi unit</name>
+      <property>biologic activity of amylase</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[bdsk'U]" CODE="[BDSK'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>Bodansky unit</name>
+      <property>biologic activity of phosphatase</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[ka'U]" CODE="[KA'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>King-Armstrong unit</name>
+      <property>biologic activity of phosphatase</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[knk'U]" CODE="[KNK'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>Kunkel unit</name>
+      <property>arbitrary biologic activity</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[mclg'U]" CODE="[MCLG'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>Mac Lagan unit</name>
+      <property>arbitrary biologic activity</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[tb'U]" CODE="[TB'U]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>tuberculin unit</name>
+      <property>biologic activity of tuberculin</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[CCID_50]" CODE="[CCID_50]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>50% cell culture infectious dose</name>
+      <printSymbol>CCID<sub>50</sub>
+      </printSymbol>
+      <property>biologic activity (infectivity) of an infectious agent preparation</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[TCID_50]" CODE="[TCID_50]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>50% tissue culture infectious dose</name>
+      <printSymbol>TCID<sub>50</sub>
+      </printSymbol>
+      <property>biologic activity (infectivity) of an infectious agent preparation</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[PFU]" CODE="[PFU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>plaque forming units</name>
+      <printSymbol>PFU</printSymbol>
+      <property>amount of an infectious agent</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[FFU]" CODE="[FFU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>focus forming units</name>
+      <printSymbol>FFU</printSymbol>
+      <property>amount of an infectious agent</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[CFU]" CODE="[CFU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>colony forming units</name>
+      <printSymbol>CFU</printSymbol>
+      <property>amount of a proliferating organism</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[BAU]" CODE="[BAU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>bioequivalent allergen unit</name>
+      <printSymbol>BAU</printSymbol>
+      <property>amount of an allergen callibrated through in-vivo testing based on the ID50EAL method of (intradermal dilution for 50mm sum of erythema diameters</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[AU]" CODE="[AU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>allergen unit</name>
+      <printSymbol>AU</printSymbol>
+      <property>procedure defined amount of an allergen using some reference standard</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[Amb'a'1'U]" CODE="[AMB'A'1'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>allergen unit for Ambrosia artemisiifolia</name>
+      <printSymbol>Amb a 1 U</printSymbol>
+      <property>procedure defined amount of the major allergen of ragweed.</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[PNU]" CODE="[PNU]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>protein nitrogen unit</name>
+      <printSymbol>PNU</printSymbol>
+      <property>procedure defined amount of a protein substance</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[Lf]" CODE="[LF]" isMetric="no" isArbitrary="yes" class="chemical">
+      <name>Limit of flocculation</name>
+      <printSymbol>Lf</printSymbol>
+      <property>procedure defined amount of an antigen substance</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="[D'ag'U]" CODE="[D'AG'U]" isMetric="no" isArbitrary="yes"
+         class="chemical">
+      <name>D-antigen unit</name>
+      <printSymbol/>
+      <property>procedure defined amount of an antigen substance</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="Np" CODE="NEP" isMetric="yes" isSpecial="yes" class="levels">
+      <name>neper</name>
+      <printSymbol>Np</printSymbol>
+      <property>level</property>
+      <value Unit="ln(1 1)" UNIT="LN(1 1)">
+         <function name="ln" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="B" CODE="B" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel</name>
+      <printSymbol>B</printSymbol>
+      <property>level</property>
+      <value Unit="lg(1 1)" UNIT="LG(1 1)">
+         <function name="lg" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="B[SPL]" CODE="B[SPL]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel sound pressure</name>
+      <printSymbol>B(SPL)</printSymbol>
+      <property>pressure level</property>
+      <value Unit="2lg(2 10*-5.Pa)" UNIT="2LG(2 10*-5.PAL)">
+         <function name="lgTimes2" value="2" Unit="10*-5.Pa"/>
+      </value>
+   </unit>
+   <unit Code="B[V]" CODE="B[V]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel volt</name>
+      <printSymbol>B(V)</printSymbol>
+      <property>electric potential level</property>
+      <value Unit="2lg(1 V)" UNIT="2LG(1 V)">
+         <function name="lgTimes2" value="1" Unit="V"/>
+      </value>
+   </unit>
+   <unit Code="B[mV]" CODE="B[MV]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel millivolt</name>
+      <printSymbol>B(mV)</printSymbol>
+      <property>electric potential level</property>
+      <value Unit="2lg(1 mV)" UNIT="2LG(1 MV)">
+         <function name="lgTimes2" value="1" Unit="mV"/>
+      </value>
+   </unit>
+   <unit Code="B[uV]" CODE="B[UV]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel microvolt</name>
+      <printSymbol>B(&#956;V)</printSymbol>
+      <property>electric potential level</property>
+      <value Unit="2lg(1 uV)" UNIT="2LG(1 UV)">
+         <function name="lgTimes2" value="1" Unit="uV"/>
+      </value>
+   </unit>
+   <unit Code="B[10.nV]" CODE="B[10.NV]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel 10 nanovolt</name>
+      <printSymbol>B(10 nV)</printSymbol>
+      <property>electric potential level</property>
+      <value Unit="2lg(10 nV)" UNIT="2LG(10 NV)">
+         <function name="lgTimes2" value="10" Unit="nV"/>
+      </value>
+   </unit>
+   <unit Code="B[W]" CODE="B[W]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel watt</name>
+      <printSymbol>B(W)</printSymbol>
+      <property>power level</property>
+      <value Unit="lg(1 W)" UNIT="LG(1 W)">
+         <function name="lg" value="1" Unit="W"/>
+      </value>
+   </unit>
+   <unit Code="B[kW]" CODE="B[KW]" isMetric="yes" isSpecial="yes" class="levels">
+      <name>bel kilowatt</name>
+      <printSymbol>B(kW)</printSymbol>
+      <property>power level</property>
+      <value Unit="lg(1 kW)" UNIT="LG(1 KW)">
+         <function name="lg" value="1" Unit="kW"/>
+      </value>
+   </unit>
+   <unit Code="st" CODE="STR" isMetric="yes" class="misc">
+      <name>stere</name>
+      <printSymbol>st</printSymbol>
+      <property>volume</property>
+      <value Unit="m3" UNIT="M3" value="1">1</value>
+   </unit>
+   <unit Code="Ao" CODE="AO" isMetric="no" class="misc">
+      <name>&#197;ngstr&#246;m</name>
+      <printSymbol>&#197;</printSymbol>
+      <property>length</property>
+      <value Unit="nm" UNIT="NM" value="0.1">0.1</value>
+   </unit>
+   <unit Code="b" CODE="BRN" isMetric="no" class="misc">
+      <name>barn</name>
+      <printSymbol>b</printSymbol>
+      <property>action area</property>
+      <value Unit="fm2" UNIT="FM2" value="100">100</value>
+   </unit>
+   <unit Code="att" CODE="ATT" isMetric="no" class="misc">
+      <name>technical atmosphere</name>
+      <printSymbol>at</printSymbol>
+      <property>pressure</property>
+      <value Unit="kgf/cm2" UNIT="KGF/CM2" value="1">1</value>
+   </unit>
+   <unit Code="mho" CODE="MHO" isMetric="yes" class="misc">
+      <name>mho</name>
+      <printSymbol>mho</printSymbol>
+      <property>electric conductance</property>
+      <value Unit="S" UNIT="S" value="1">1</value>
+   </unit>
+   <unit Code="[psi]" CODE="[PSI]" isMetric="no" class="misc">
+      <name>pound per sqare inch</name>
+      <printSymbol>psi</printSymbol>
+      <property>pressure</property>
+      <value Unit="[lbf_av]/[in_i]2" UNIT="[LBF_AV]/[IN_I]2" value="1">1</value>
+   </unit>
+   <unit Code="circ" CODE="CIRC" isMetric="no" class="misc">
+      <name>circle</name>
+      <printSymbol>circ</printSymbol>
+      <property>plane angle</property>
+      <value Unit="[pi].rad" UNIT="[PI].RAD" value="2">2</value>
+   </unit>
+   <unit Code="sph" CODE="SPH" isMetric="no" class="misc">
+      <name>spere</name>
+      <printSymbol>sph</printSymbol>
+      <property>solid angle</property>
+      <value Unit="[pi].sr" UNIT="[PI].SR" value="4">4</value>
+   </unit>
+   <unit Code="[car_m]" CODE="[CAR_M]" isMetric="no" class="misc">
+      <name>metric carat</name>
+      <printSymbol>ct<sub>m</sub>
+      </printSymbol>
+      <property>mass</property>
+      <value Unit="g" UNIT="G" value="0.2">0.2</value>
+   </unit>
+   <unit Code="[car_Au]" CODE="[CAR_AU]" isMetric="no" class="misc">
+      <name>carat of gold alloys</name>
+      <printSymbol>ct<sub>
+            <r>Au</r>
+         </sub>
+      </printSymbol>
+      <property>mass fraction</property>
+      <value Unit="/24" UNIT="/24" value="1">1</value>
+   </unit>
+   <unit Code="[smoot]" CODE="[SMOOT]" isMetric="no" class="misc">
+      <name>Smoot</name>
+      <printSymbol/>
+      <property>length</property>
+      <value Unit="[in_i]" UNIT="[IN_I]" value="67">67</value>
+   </unit>
+   <unit Code="bit_s" CODE="BIT_S" isMetric="no" isSpecial="yes" class="infotech">
+      <name>bit</name>
+      <printSymbol>bit<sub>s</sub>
+      </printSymbol>
+      <property>amount of information</property>
+      <value Unit="ld(1 1)" UNIT="ld(1 1)">
+         <function name="ld" value="1" Unit="1"/>
+      </value>
+   </unit>
+   <unit Code="bit" CODE="BIT" isMetric="yes" class="infotech">
+      <name>bit</name>
+      <printSymbol>bit</printSymbol>
+      <property>amount of information</property>
+      <value Unit="1" UNIT="1" value="1">1</value>
+   </unit>
+   <unit Code="By" CODE="BY" isMetric="yes" class="infotech">
+      <name>byte</name>
+      <printSymbol>B</printSymbol>
+      <property>amount of information</property>
+      <value Unit="bit" UNIT="bit" value="8">8</value>
+   </unit>
+   <unit Code="Bd" CODE="Bd" isMetric="yes" class="infotech">
+      <name>baud</name>
+      <printSymbol>Bd</printSymbol>
+      <property>signal transmission rate</property>
+      <value Unit="/s" UNIT="/s" value="1">1</value>
+   </unit>
+   <prefix Code="Ki" CODE="KIB">
+      <name>kibi</name>
+      <printSymbol>Ki</printSymbol>
+      <value value="1024">1024</value>
+   </prefix>
+   <prefix Code="Mi" CODE="MIB">
+      <name>mebi</name>
+      <printSymbol>Mi</printSymbol>
+      <value value="1048576">1048576</value>
+   </prefix>
+   <prefix Code="Gi" CODE="GIB">
+      <name>gibi</name>
+      <printSymbol>Gi</printSymbol>
+      <value value="1073741824">1073741824</value>
+   </prefix>
+   <prefix Code="Ti" CODE="TIB">
+      <name>tebi</name>
+      <printSymbol>Ti</printSymbol>
+      <value value="1099511627776">1099511627776</value>
+   </prefix>
+</root>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum/.classpath b/bundles/org.eclipse.uomo.ucum/.classpath
new file mode 100644
index 0000000..c892e36
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry exported="true" kind="lib" path="lib/icu4j-50_1_1.jar"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.ucum/.gitignore b/bundles/org.eclipse.uomo.ucum/.gitignore
new file mode 100644
index 0000000..2c36b17
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/.gitignore
@@ -0,0 +1,2 @@
+/target
+/.settings
diff --git a/bundles/org.eclipse.uomo.ucum/.project b/bundles/org.eclipse.uomo.ucum/.project
new file mode 100644
index 0000000..a5bb896
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/.project
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.ucum</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.ucum/.springBeans b/bundles/org.eclipse.uomo.ucum/.springBeans
new file mode 100644
index 0000000..4dff647
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.3.2.201003220227-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.ucum/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.ucum/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e37c1b8
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.ucum
+Bundle-SymbolicName: org.eclipse.uomo.ucum
+Bundle-Version: 0.6.0.qualifier
+Export-Package: org.eclipse.uomo.ucum,
+ org.eclipse.uomo.ucum.canonical,
+ org.eclipse.uomo.ucum.expression,
+ org.eclipse.uomo.ucum.impl,
+ org.eclipse.uomo.ucum.model,
+ org.eclipse.uomo.ucum.parsers,
+ org.eclipse.uomo.ucum.special
+Require-Bundle: org.eclipse.uomo.core;bundle-version="0.6.0",
+ org.eclipse.uomo.util;bundle-version="0.2.6",
+ org.eclipse.uomo.xml;bundle-version="0.2.0",
+ org.eclipse.uomo.units;bundle-version="0.6.0",
+ org.apache.commons.lang;bundle-version="2.3.0",
+ org.unitsofmeasurement.unit-api;bundle-version="0.6.1"
+Bundle-Vendor: Eclipse OSBP
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Import-Package: org.eclipse.osgi.util;version="1.1.0"
+Bundle-ClassPath: lib/icu4j-50_1_1.jar,.
diff --git a/bundles/org.eclipse.uomo.ucum/build.properties b/bundles/org.eclipse.uomo.ucum/build.properties
new file mode 100644
index 0000000..01949b5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/build.properties
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+bin.includes = META-INF/,\
+               .,\
+               lib/icu4j-50_1_1.jar
diff --git a/bundles/org.eclipse.uomo.ucum/lib/icu4j-50_1_1.jar b/bundles/org.eclipse.uomo.ucum/lib/icu4j-50_1_1.jar
new file mode 100644
index 0000000..4994a5c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/lib/icu4j-50_1_1.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.ucum/pom.xml b/bundles/org.eclipse.uomo.ucum/pom.xml
new file mode 100644
index 0000000..37d834f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/pom.xml
@@ -0,0 +1,14 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.ucum</artifactId>
+	<name>UOMo UCUM</name>
+	<packaging>eclipse-plugin</packaging>
+
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/ohf/utilities/OHFException.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/ohf/utilities/OHFException.java
new file mode 100644
index 0000000..3219214
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/ohf/utilities/OHFException.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ohf.utilities;
+
+import org.eclipse.uomo.core.UOMoException;
+
+
+/**
+ * @author Werner Keil
+ * @deprecated for backwards compatibility
+ */
+public class OHFException extends UOMoException {
+
+	private static final long serialVersionUID = 3333261489669700628L;
+
+	public OHFException(String message) {
+		super(message);
+	}
+
+	public OHFException(String message, Throwable causingException) {
+		super(message, causingException);
+	}
+
+	public OHFException(Throwable causingException) {
+		super(causingException);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/Search.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/Search.java
new file mode 100644
index 0000000..b70ba33
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/Search.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2010, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.ucum;
+
+import java.util.List;
+
+import org.eclipse.uomo.ucum.model.Concept;
+import org.eclipse.uomo.ucum.model.ConceptKind;
+import org.eclipse.uomo.ucum.model.UcumModel;
+
+/**
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ *
+ */
+public interface Search {
+	public List<Concept> doSearch(UcumModel model, ConceptKind kind,
+			String text, boolean isRegex);
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumFormatService.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumFormatService.java
new file mode 100644
index 0000000..a03a847
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumFormatService.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.ucum;
+
+import java.io.IOException;
+import java.text.ParsePosition;
+
+import org.unitsofmeasurement.service.UnitFormatService;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p> This interface provides methods for OSGi bundles to parse/format units
+ *     as per the <a href="http://www.unitsofmeasure.org/">
+ *     Unified Code for Units of Measure (UCUM)</a> specification.</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @see <a href="http://aurora.regenstrief.org/~ucum/ucum.html">UCUM Full Specification</a>
+ * @version 1.1 ($Revision: 306 $), $Date: 2010-10-29 21:42:27 +0100 (Fr, 29 Okt 2010) $
+ */
+public interface UcumFormatService extends UnitFormatService {
+
+    /**
+     * Formats the specified unit.
+     *
+     * @param unit the unit to format.
+     * @param appendable the appendable destination.
+     * @return the appendable destination passed in with formatted text appended.
+     * @throws IOException if an error occurs.
+     */
+    Appendable format(Unit<?> unit, Appendable appendable)
+            throws IOException;
+
+    /**
+     * Parses a portion of the specified {@link CharSequence} from the
+     * specified position to produce a unit. If there is no unit to parse
+     * the unitary unit (dimensionless) is returned.
+     *
+     * @param csq the <code>CharSequence</code> to parse.
+     * @param cursor the cursor holding the current parsing index or <code>
+     *        null</code> to parse the whole character sequence.
+     * @return the unit parsed from the specified character sub-sequence.
+     * @throws IllegalArgumentException if any problem occurs while parsing the
+     *         specified character sequence (e.g. illegal syntax).
+     */
+    Unit<?> parse(CharSequence csq, ParsePosition cursor)
+            throws IllegalArgumentException;
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumService.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumService.java
new file mode 100644
index 0000000..d80894d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/UcumService.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.uomo.core.impl.Pair;
+import org.eclipse.uomo.core.IVersion;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.ucum.model.Concept;
+import org.eclipse.uomo.ucum.model.ConceptKind;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.UcumModel;
+
+
+/**
+ * General UCUM Service
+ * This is a tightly bound interface - consumers use the internal model classes
+ * 
+ * TODO: define a remoteable service that interface that doesn't express the 
+ * functionality using internal model classes
+ * @author Grahame Grieve
+ * @author Werner Keil
+ *
+ */
+public interface UcumService {
+
+	/**
+	 * provided for various utility uses. Should not be used 
+	 * for general use
+	 * 
+	 * @return the model
+	 */
+	public UcumModel getModel();
+
+	// TODO replace this with a more generic Module definition (->Jigsaw, OSGi or SDJ)
+	public class UcumVersionDetails implements IVersion {
+		private final Date releaseDate;
+		private final String version;
+		/**
+		 * @param releaseDate
+		 * @param version
+		 */
+		public UcumVersionDetails(Date releaseDate, String version) {
+			super();
+			this.releaseDate = releaseDate;
+			this.version = version;
+		}
+		/**
+		 * @return the releaseDate
+		 */
+		public Date getReleaseDate() {
+			return releaseDate;
+		}
+		/**
+		 * @return the version
+		 */
+		public String getVersion() {
+			return version;
+		}
+		
+	}
+	
+	/**
+	 * return Ucum Identification details
+	 */
+	public UcumVersionDetails ucumIdentification();
+
+
+	/**
+	 * Check UCUM. Note that this stands as a test of the service
+	 * more than UCUM itself (for version 1.7, there are no known
+	 * semantic errors in UCUM). But you should always run this test at least
+	 * once with the version of UCUM you are using to ensure that 
+	 * the service implementation correctly understands the UCUM data
+	 * to which it is bound
+	 *   
+	 * @return a list of internal errors in the UCUM spec.
+	 * 
+	 */
+	public List<String> validateUCUM();
+
+	/**
+	 * Search through the UCUM concepts for any concept containing matching text.
+	 * Search will be limited to the kind of concept defined by kind, or all if kind
+	 * is null
+	 * 
+	 * @param kind - can be null. scope of search
+	 * @param text - required
+	 * @param isRegex
+	 * @return
+	 */
+	public List<Concept> search(ConceptKind kind, String text, boolean isRegex);
+
+	/**
+	 * return a list of the defined types of units in this UCUM version
+	 * 
+	 * @return
+	 */
+	public Set<String> getProperties();
+
+	/**
+	 * validate whether a unit code are valid UCUM units
+	 *  
+	 * @param units - the unit code to check
+	 * @return nil if valid, or an error message describing the problem
+	 */
+	public String validate(String unit);
+
+	/**
+	 * given a unit, return a formal description of what the units stand for using
+	 * full names 
+	 * @param units the unit code
+	 * @return formal description
+	 * @throws UOMoRuntimeException 
+	 */
+	public String analyse(String unit) throws UOMoRuntimeException;
+	
+	/**
+	 * validate whether a units are valid UCUM units and additionally require that the 
+	 * units from a particular property
+	 *  
+	 * @param units - the unit code to check
+	 * @return nil if valid, or an error message describing the problem
+	 */
+	public String validateInProperty(String unit, String property);
+
+	/**
+	 * validate whether a units are valid UCUM units and additionally require that the 
+	 * units match a particular base canonical unit
+	 *  
+	 * @param units - the unit code to check
+	 * @return nil if valid, or an error message describing the problem
+	 */
+	public String validateCanonicalUnits(String unit, String canonical);
+
+	/**
+	 * given a set of units, return their canonical form
+	 * @param unit
+	 * @return the canonical form
+	 * @throws UOMoRuntimeException 
+	 */
+	public String getCanonicalUnits(String unit) throws UOMoRuntimeException;
+
+	/**
+	 * for a given canonical unit, return all the defined units that have the 
+	 * same canonical unit. 
+	 * 
+	 * @param code
+	 * @return
+	 * @throws UOMoRuntimeException
+	 */
+	public List<DefinedUnit> getDefinedForms(String code) throws UOMoRuntimeException;
+
+	/**
+	 * given a value/unit pair, return the canonical form as a value/unit pair
+	 * 
+	 * 1 mm -> 1e-3 m
+	 * @param value
+	 * @return
+	 * @throws UOMoRuntimeException 
+	 */
+	public Pair<Number, String> getCanonicalForm(Pair<Number, String> value) throws UOMoRuntimeException;
+
+	/**
+	 * given a value and source unit, return the value in the given dest unit
+	 * an exception is thrown if the conversion is not possible
+	 * 
+	 * @param value
+	 * @param sourceUnit
+	 * @param destUnit
+	 * @return the value if a conversion is possible
+	 * @throws UOMoRuntimeException
+	 */
+	public Number convert(Number value, String sourceUnit, String destUnit) throws UOMoRuntimeException;
+
+	/**
+	 * multiply two value/units pairs together and return the result in canonical units
+	 * 
+	 * Note: since the units returned are canonical, 
+	 * @param o1
+	 * @param o2
+	 * @return
+	 */
+	public Pair<Number, String> multiply(Pair<Number, String> o1, Pair<Number, String> o2);
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Component.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Component.java
new file mode 100644
index 0000000..cdcc47f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Component.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.expression;
+
+public abstract class Component {
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Factor.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Factor.java
new file mode 100644
index 0000000..91d3e61
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Factor.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.expression;
+
+
+public class Factor extends Component {
+	
+	private int value;
+
+	/**
+	 * 
+	 */
+	public Factor() {
+		super();
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * @param value
+	 */
+	public Factor(int value) {
+		super();
+		this.value = value;
+	}
+
+	/**
+	 * @return the value
+	 */
+	public int getValue() {
+		return value;
+	}
+
+	/**
+	 * @param value the value to set
+	 */
+	public void setValue(int value) {
+		this.value = value;
+	}
+
+	
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Operator.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Operator.java
new file mode 100644
index 0000000..e3c0724
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Operator.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.expression;
+
+public enum Operator {
+	MULTIPLICATION,
+	DIVISION;
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Symbol.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Symbol.java
new file mode 100644
index 0000000..3f7aaa3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Symbol.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.expression;
+
+import org.eclipse.uomo.ucum.model.Prefix;
+import org.eclipse.uomo.ucum.model.UcumUnit;
+
+public class Symbol extends Component {
+
+	private UcumUnit unit; // may be Base Unit or DefinedUnit
+	private Prefix prefix;  // only if unit is metric 
+	private int exponent;
+		
+	/**
+	 * 
+	 */
+	public Symbol() {
+		super();
+	}
+
+	/**
+	 * @param unit
+	 * @param prefix
+	 * @param exponent
+	 */
+	public Symbol(UcumUnit unit, Prefix prefix, int exponent) {
+		super();
+		this.unit = unit;
+		this.prefix = prefix;
+		this.exponent = exponent;
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public UcumUnit getUnit() {
+		return unit;
+	}
+
+	/**
+	 * @param unit the unit to set
+	 */
+	public void setUnit(UcumUnit unit) {
+		this.unit = unit;
+	}
+
+	/**
+	 * @return the prefix
+	 */
+	public Prefix getPrefix() {
+		return prefix;
+	}
+
+	/**
+	 * @param prefix the prefix to set
+	 */
+	public void setPrefix(Prefix prefix) {
+		this.prefix = prefix;
+	}
+
+	/**
+	 * @return the exponent
+	 */
+	public int getExponent() {
+		return exponent;
+	}
+
+	/**
+	 * @param exponent the exponent to set
+	 */
+	public void setExponent(int exponent) {
+		this.exponent = exponent;
+	}
+	
+	public boolean hasPrefix() {
+		return prefix != null;
+	}
+
+	public void invertExponent() {
+		exponent = -exponent;
+	}
+	
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Term.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Term.java
new file mode 100644
index 0000000..4520999
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/expression/Term.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.expression;
+
+public class Term extends Component {
+
+	// op-term where op = /
+	// component
+	// component-op-term
+	private Component comp;
+	private Operator op;
+	private Term term;
+	/**
+	 * 
+	 */
+	public Term() {
+		super();
+	}
+	/**
+	 * @return the comp
+	 */
+	public Component getComp() {
+		return comp;
+	}
+	/**
+	 * @param comp the comp to set
+	 */
+	public void setComp(Component comp) {
+		this.comp = comp;
+	}
+	/**
+	 * @return the op
+	 */
+	public Operator getOp() {
+		return op;
+	}
+	/**
+	 * @param op the op to set
+	 */
+	public void setOp(Operator op) {
+		this.op = op;
+	}
+	/**
+	 * @return the term
+	 */
+	public Term getTerm() {
+		return term;
+	}
+	/**
+	 * @param term the term to set
+	 */
+	public void setTerm(Term term) {
+		this.term = term;
+	}
+	
+	public boolean hasComp() {
+		return comp != null;
+	}
+
+	public boolean hasOp() {
+		return op != null;
+	}
+	
+	public boolean hasTerm() {
+		return term != null;
+	}
+	public void setTermCheckOp(Term term) {
+		setTerm(term);
+		if (term == null)
+			setOp(null);
+	}
+
+	
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/Canonical.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/Canonical.java
new file mode 100644
index 0000000..68694b3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/Canonical.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.impl;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.ucum.expression.Term;
+
+// TODO replace this with extended QuantityAmount
+class Canonical {
+
+	private BigDecimal value;
+	private Term unit;
+	
+	/**
+	 * @param value
+	 * @param unit
+	 */
+	public Canonical(BigDecimal value, Term unit) {
+		super();
+		this.value = value;
+		this.unit = unit;
+	}
+
+	/**
+	 * @return the value
+	 */
+	public BigDecimal getValue() {
+		return value;
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public Term getUnit() {
+		return unit;
+	}
+
+	/**
+	 * @param value the value to set
+	 */
+	public void setValue(BigDecimal value) {
+		this.value = value;
+	}
+
+	void multiplyValue(Number number) {
+		value = value.multiply((BigDecimal) number);		
+	}
+
+	void multiplyValue(int multiplicand) {
+		value = value.multiply(new BigDecimal(multiplicand));		
+	}
+
+	public boolean hasUnit() {
+		return unit != null;
+	}
+
+	/**
+	 * @param unit the unit to set
+	 */
+	public void setUnit(Term unit) {
+		this.unit = unit;
+	}
+
+	void divideValue(BigDecimal divisor) {
+		value = value.divide(divisor, new MathContext(20));		
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/SearchImpl.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/SearchImpl.java
new file mode 100644
index 0000000..336e691
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/SearchImpl.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.ucum.Search;
+import org.eclipse.uomo.ucum.model.Concept;
+import org.eclipse.uomo.ucum.model.ConceptKind;
+import org.eclipse.uomo.ucum.model.Prefix;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.model.UcumUnit;
+
+class SearchImpl implements Search {
+
+	public List<Concept> doSearch(UcumModel model, ConceptKind kind, String text, boolean isRegex) {
+		List<Concept> concepts = new ArrayList<Concept>();
+		if (kind == null || kind == ConceptKind.PREFIX)
+			searchPrefixes(concepts, model.getPrefixes(), text, isRegex);
+		if (kind == null || kind == ConceptKind.BASEUNIT)
+			searchUnits(concepts, model.getBaseUnits(), text, isRegex);
+		if (kind == null || kind == ConceptKind.UNIT)
+			searchUnits(concepts, model.getDefinedUnits(), text, isRegex);
+		return concepts;
+	}
+	
+	private void searchUnits(List<Concept> concepts, List<? extends UcumUnit> units, String text, boolean isRegex) {
+		for (UcumUnit unit : units) {
+			if (matchesUnit(unit, text, isRegex))
+				concepts.add(unit);
+		}
+	}
+
+	private boolean matchesUnit(UcumUnit unit, String text, boolean isRegex) {
+		return matches(unit.getProperty(), text, isRegex) || matchesConcept(unit, text, isRegex);
+	}
+
+	private void searchPrefixes(List<Concept> concepts, List<? extends Prefix> prefixes, String text, boolean isRegex) {
+		for (Concept concept : prefixes) {
+			if (matchesConcept(concept, text, isRegex))
+				concepts.add(concept);
+		}		
+	}
+
+	private boolean matchesConcept(Concept concept, String text, boolean isRegex) {
+		for (String name : concept.getNames()) {
+			if (matches(name, text, isRegex))
+				return true;
+		}
+		if (matches(concept.getCode(), text, isRegex))
+			return true;
+		if (matches(concept.getCodeUC(), text, isRegex))
+			return true;
+		if (matches(concept.getPrintSymbol(), text, isRegex))
+			return true;
+		return false;
+	}
+
+	private boolean matches(String value, String text, boolean isRegex) {
+		return (value != null) && ((isRegex  && value.matches(text)) || (!isRegex && value.toLowerCase().contains(text.toLowerCase())));
+	}
+
+
+}
+
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumConverter.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumConverter.java
new file mode 100644
index 0000000..68eb9ed
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumConverter.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.impl;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.isConsoleOutput;
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+import static org.eclipse.uomo.ucum.model.ConceptKind.*;
+import static org.eclipse.uomo.ucum.expression.Operator.*;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.ucum.expression.Component;
+import org.eclipse.uomo.ucum.expression.Factor;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.parsers.ExpressionComposer;
+import org.eclipse.uomo.ucum.parsers.ExpressionParser;
+import org.eclipse.uomo.ucum.special.SpecialUnitHandler;
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.util.Registry;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * = [mu_0] = 4.[pi].10*-7.N/A2 = (g.m/s2)/(C/s)2? = g.m/s2/(C2/s2) =
+ * g.m/s2/C2.s2 = g.m/C2.s2/s2 = g.m/C2 = m.g.C-2
+ * 
+ * @author Grahame Grieve
+ * @author Werner Keil
+ */
+class UcumConverter extends AbstractConverter {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -895607408258138526L;
+	private final UcumModel model;
+	private final Registry<SpecialUnitHandler> handlers;
+	private final UnitConverter compound;
+	
+	private Factor one = new Factor(1);
+
+	/**
+	 * @param model
+	 */
+	public UcumConverter(UcumModel model, Registry handlers) {
+		super();
+		this.model = model;
+		this.handlers = handlers;
+		List<UnitConverter> compounds = getCompoundConverters();
+		compound = compounds.get(0);
+	}
+
+	public Canonical convert(Term term) throws UOMoRuntimeException {
+		return convertTerm(term);
+	}
+
+	private Canonical convertTerm(Term term) throws UOMoRuntimeException {
+		Canonical res = new Canonical(BigDecimal.ONE, new Term());
+		if (term.hasComp())
+			res.getUnit().setComp(convertComp(res, term.getComp()));
+		if (term.hasOp())
+			res.getUnit().setOp(term.getOp());
+		if (term.hasTerm()) {
+			Canonical t = convertTerm(term.getTerm());
+			res.setValue(res.getValue().multiply(t.getValue()));
+			if (t.hasUnit())
+				res.getUnit().setTermCheckOp(t.getUnit());
+			else
+				res.getUnit().setOp(null);
+		}
+
+		// normalise
+		debug("normalise", res.getUnit()); //$NON-NLS-1$
+		if (res.getUnit().hasOp() && res.getUnit().getOp() == DIVISION) {
+			res.getUnit().setOp(MULTIPLICATION);
+			flipExponents(res.getUnit().getTerm());
+			debug("flipped", res.getUnit()); //$NON-NLS-1$
+		}
+
+		if (!res.getUnit().hasComp() || res.getUnit().getComp() == one) {
+			res.setUnit(res.getUnit().getTerm());
+			debug("trimmed", res.getUnit()); //$NON-NLS-1$
+		}
+
+		// everything in scope is a multiplication operation. If comp is a term,
+		// then
+		// we are going to tack our term on the end of that term as a
+		// multiplication, and
+		// make comp our term
+
+		if (res.hasUnit() && res.getUnit().hasComp()
+				&& res.getUnit().getComp() instanceof Term) {
+			Term end = getEndTerm((Term) res.getUnit().getComp());
+			assert end.getOp() == null;
+			end.setOp(MULTIPLICATION);
+			end.setTermCheckOp(res.getUnit().getTerm());
+			res.setUnit((Term) res.getUnit().getComp());
+			debug("reorged", res.getUnit()); //$NON-NLS-1$
+		}
+
+		if (res.hasUnit()
+				&& (!res.getUnit().hasComp() || res.getUnit().getComp() == one)) {
+			res.setUnit(res.getUnit().getTerm());
+			debug("trimmed", res.getUnit()); //$NON-NLS-1$
+		}
+		// now we have a linear list of terms, each with one component.
+		// we scan through the list looking for common components to factor out
+		// we have to scan into the list because we may have deep duplicates
+		// from the previous flattening operation. we also remove anything
+		// that's
+		// ended up with an exponent of 0 during this operation
+		if (res.hasUnit())
+			res.setUnit(removeDuplicateComponents(res.getUnit()));
+
+		if (res.hasUnit() && !res.getUnit().hasTerm())
+			res.getUnit().setOp(null);
+		debug("norm finished", res.getUnit()); //$NON-NLS-1$
+		// System.out.println("value: "+res.getValue().toPlainString()+"; units: "+new
+		// ExpressionComposer().compose(res.getUnit()));
+		return res;
+	}
+
+	private void debug(String state, Term unit) {
+		if (isConsoleOutput()) { // avoiding any call if no debug output set
+			println(state + ": " + new ExpressionComposer().compose(unit)); //$NON-NLS-1$
+		}
+	}
+
+	private Term getEndTerm(Term term) {
+		if (term.hasTerm())
+			return getEndTerm(term.getTerm());
+		else
+			return term;
+	}
+
+	private Term removeDuplicateComponents(Term unit) {
+		if (unit == null)
+			return null;
+		assert unit.getComp() instanceof Symbol; // because that should be all
+													// that's left
+		Symbol symO = (Symbol) unit.getComp();
+		Term inner = findDuplicateCompOwner(unit.getTerm(), symO);
+		if (inner != null) {
+			Symbol symI = (Symbol) inner.getComp();
+			symI.setExponent(symI.getExponent() + symO.getExponent());
+			return removeDuplicateComponents(unit.getTerm());
+		}
+		if (symO.getExponent() == 0)
+			return removeDuplicateComponents(unit.getTerm());
+		unit.setTermCheckOp(removeDuplicateComponents(unit.getTerm()));
+		return unit;
+	}
+
+	private Term findDuplicateCompOwner(Term term, Symbol comp) {
+		if (term == null)
+			return null;
+		if (term.getComp() instanceof Symbol) {
+			Symbol sym = (Symbol) term.getComp();
+			if (sym.getPrefix() == comp.getPrefix() && // i.e. null
+					sym.getUnit() == comp.getUnit())
+				return term;
+		}
+		return findDuplicateCompOwner(term.getTerm(), comp);
+	}
+
+	private void flipExponents(Term term) {
+		if (term.getComp() instanceof Symbol) {
+			((Symbol) term.getComp()).invertExponent();
+		}
+		if (term.hasTerm()) {
+			flipExponents(term.getTerm());
+		}
+	}
+
+	private Component convertComp(Canonical ctxt, Component comp)
+			throws UOMoRuntimeException {
+		if (comp instanceof Term) {
+			Canonical t = convertTerm((Term) comp);
+			ctxt.multiplyValue(t.getValue());
+			return t.getUnit();
+		} else if (comp instanceof Factor) {
+			ctxt.multiplyValue(((Factor) comp).getValue());
+			return one; // nothing to convert
+		} else if (comp instanceof Symbol)
+			return convertSymbol(ctxt, (Symbol) comp);
+		else
+			throw new UOMoRuntimeException("unknown component type " //$NON-NLS-1$
+					+ comp.getClass().toString());
+	}
+
+	private Component convertSymbol(Canonical ctxt, Symbol comp)
+			throws UOMoRuntimeException {
+		if (comp.hasPrefix()) {
+//			ctxt.multiplyValue(comp.getPrefix().getValue());
+			ctxt.multiplyValue(((BigDecimal)comp.getPrefix().getValue()).pow(
+					comp.getExponent(),	MathContext.DECIMAL128));
+		}
+
+		if (comp.getUnit().getKind() == BASEUNIT) {
+			Symbol res = new Symbol();
+			res.setUnit(comp.getUnit());
+			res.setExponent(comp.getExponent());
+			return res;
+		} else {
+			DefinedUnit unit = (DefinedUnit) comp.getUnit();
+			String u = unit.getValue().getUnit();
+			if (unit.isSpecial()) {
+				if (!handlers.exists(unit.getCode()))
+					throw new UOMoRuntimeException("Not handled yet (special unit)"); //$NON-NLS-1$
+				else {
+					u = handlers.get(unit.getCode()).getUnits();
+					ctxt.multiplyValue(handlers.get(unit.getCode()).value());
+				}
+			} else
+				ctxt.multiplyValue(unit.getValue().value());
+			Term canonical = new ExpressionParser(model).parse(u);
+			if (canonical.hasComp() && !canonical.hasOp()
+					&& !canonical.hasTerm()) {
+				Component ret = convertComp(ctxt, canonical.getComp());
+				if (comp.getExponent() == 1)
+					return ret;
+				else if (ret instanceof Factor) {
+					((Factor) ret).setValue(comp.getExponent()
+							+ ((Factor) ret).getValue());
+					return ret;
+				} else if (ret instanceof Symbol) {
+					((Symbol) ret).setExponent(comp.getExponent()
+							* ((Symbol) ret).getExponent());
+					return ret;
+				} else if (ret instanceof Term) {
+					applyExponent((Term) ret, comp.getExponent());
+					return ret;
+				} else
+					throw new UOMoRuntimeException("unknown component type " //$NON-NLS-1$
+							+ comp.getClass().toString());
+			} else {
+				Canonical t1 = convertTerm(canonical);
+				Term ret = t1.getUnit();
+				if (comp.getExponent() == -1 && ret.hasComp() && ret.hasOp()
+						&& ret.hasTerm() && ret.getTerm().hasComp()
+						&& !ret.getTerm().hasOp() && !ret.getTerm().hasTerm()) {
+					Component t = ret.getTerm().getComp();
+					ret.getTerm().setComp(ret.getComp());
+					ret.setComp(t);
+					ctxt.divideValue(t1.getValue());
+					return ret;
+				} else if (comp.getExponent() != 1) {
+					ctxt.multiplyValue(t1.getValue());
+					// what we have to do is push the exponent into the all the
+					// symbols contained herein
+					applyExponent(ret, comp.getExponent());
+					return ret;
+				} else {
+					ctxt.multiplyValue(t1.getValue());
+					return ret;
+				}
+			}
+		}
+	}
+
+	private void applyExponent(Term term, int exponent) {
+		if (term == null)
+			return;
+		if (term.hasComp()) {
+			if (term.getComp() instanceof Term) {
+				applyExponent((Term) term.getComp(), exponent);
+			} else if (term.getComp() instanceof Symbol) {
+				Symbol sym = (Symbol) term.getComp();
+				sym.setExponent(sym.getExponent() * exponent);
+			}
+
+		}
+		applyExponent(term.getTerm(), exponent);
+	}
+
+	public UnitConverter concatenate(UnitConverter converter) {
+		return compound.concatenate(converter);
+	}
+
+	public double convert(double value) {
+		return compound.convert(value);
+	}
+
+	public BigDecimal convert(BigDecimal value, MathContext ctx)
+			throws ArithmeticException {
+		return compound.convert(value, ctx);
+	}
+
+	public List<UnitConverter> getCompoundConverters() {
+		final List<UnitConverter> compound = new ArrayList<UnitConverter>();
+		compound.add(this);
+		return compound;
+	}
+
+	public UnitConverter inverse() {
+		return compound.inverse();
+	}
+
+	public boolean isIdentity() {
+		return false;
+	}
+
+	public boolean isLinear() {
+		return false;
+	}
+
+	public Number convert(Number value) {
+		return compound.convert(value);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumEssenceService.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumEssenceService.java
new file mode 100644
index 0000000..0663ce4
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumEssenceService.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2012, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - fixes and improvements
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.impl;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+
+import java.io.File;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.core.impl.Pair;
+import org.eclipse.uomo.ucum.UcumService;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+import org.eclipse.uomo.ucum.model.BaseUnit;
+import org.eclipse.uomo.ucum.model.Concept;
+import org.eclipse.uomo.ucum.model.ConceptKind;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.parsers.DefinitionParser;
+import org.eclipse.uomo.ucum.parsers.ExpressionComposer;
+import org.eclipse.uomo.ucum.parsers.ExpressionParser;
+import org.eclipse.uomo.ucum.parsers.FormalStructureComposer;
+import org.eclipse.uomo.ucum.special.SpecialUnitRegistry;
+
+/**
+ * implements UCUM services. Applications must provide a copy of
+ * ucum-essence.xml as either a stream or a file name to create the services.
+ * 
+ * the provided ucum-essence.xml must be released on 25 Apr 2008 or more recent.
+ * Note that if the ucum-essence.xml file does not contain a release date on an
+ * attribute of the root element, it is not more recent than this date (Gunther
+ * added it on this date for this usage, thanks)
+ * 
+ * @author Grahame Grieve
+ * @author Werner Keil
+ */
+public class UcumEssenceService implements UcumService {
+
+	/**
+	 * UCUM ID
+	 */
+	public static final String UCUM_OID = "2.16.840.1.113883.6.8";
+
+	private final UcumModel model;
+	private SpecialUnitRegistry handlers = new SpecialUnitRegistry();
+
+	/**
+	 * Create an instance of Ucum services. Stream must point to a valid
+	 * ucum-essence file (see class documentation)
+	 */
+	public UcumEssenceService(InputStream stream) throws UOMoRuntimeException {
+		super();
+		assert stream != null : paramError("factory", "stream",
+				"must not be null");
+		try {
+			model = new DefinitionParser().parse(stream);
+		} catch (Exception e) {
+			throw new UOMoRuntimeException(e);
+		}
+	}
+
+	/**
+	 * Create an instance of Ucum services. filename must point to a valid
+	 * ucum-essence file (see class documentation)
+	 */
+	public UcumEssenceService(String filename) throws UOMoRuntimeException {
+		super();
+		assert new File(filename).exists() : paramError("factory", "file",
+				"must exist");
+		try {
+			model = new DefinitionParser().parse(filename);
+		} catch (Exception e) {
+			throw new UOMoRuntimeException(e);
+		}
+	}
+
+	private String paramError(String method, String param, String msg) {
+		return getClass().getName() + "." + method + "." + param
+				+ " is not acceptable: " + msg;
+	}
+
+	public UcumVersionDetails ucumIdentification() {
+		return new UcumVersionDetails(model.getRevisionDate(),
+				model.getVersion());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.ucum.UcumServiceEx#getModel()
+	 */
+	public UcumModel getModel() {
+		return model;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.ucum.UcumServiceEx#search(org.eclipse.uomo.ucum.model.
+	 * ConceptKind, java.lang.String, boolean)
+	 */
+	public List<Concept> search(ConceptKind kind, String text, boolean isRegex) {
+		assert checkStringParam(text) : paramError("search", "text",
+				"must not be null or empty");
+		return new SearchImpl().doSearch(model, kind, text, isRegex);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.ucum.UcumService#validateUCUM()
+	 */
+	public List<String> validateUCUM() {
+		return new UcumValidator(model, handlers).validate();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.ucum.UcumService#getProperties()
+	 */
+	public Set<String> getProperties() {
+		Set<String> result = new HashSet<String>();
+		for (DefinedUnit unit : model.getDefinedUnits()) {
+			result.add(unit.getProperty());
+		}
+		for (BaseUnit unit : model.getBaseUnits()) {
+			result.add(unit.getProperty());
+		}
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ohf.ucum.UcumServiceEx#validate(java.lang.String)
+	 */
+	public String validate(String unit) {
+		assert unit != null : paramError("validate", "unit", "must not be null");
+		try {
+			new ExpressionParser(model).parse(unit);
+			return null;
+		} catch (UOMoRuntimeException e) {
+			return e.getMessage();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ohf.ucum.UcumServiceEx#validateInProperty(java.lang.String,
+	 * java.lang.String)
+	 */
+	public String validateInProperty(String unit, String property) {
+		assert checkStringParam(unit) : paramError("validate", "unit",
+				"must not be null or empty");
+		assert checkStringParam(property) : paramError("validateInProperty",
+				"property", "must not be null or empty");
+		try {
+			Term term = new ExpressionParser(model).parse(unit);
+			Canonical can = new UcumConverter(model, handlers).convert(term);
+			term = can.getUnit();
+			String cu = new ExpressionComposer().compose(term);
+			if (term.hasComp() && !term.hasOp()
+					&& term.getComp() instanceof Symbol) {
+				Symbol sym = (Symbol) term.getComp();
+				if (sym.getExponent() == 1 && sym.getUnit() instanceof BaseUnit) {
+					BaseUnit b = (BaseUnit) sym.getUnit();
+					if (property.equals(b.getProperty()))
+						return null;
+					else
+						return "unit " + unit + " is of the property type "
+								+ b.getProperty() + " (" + cu + "), not "
+								+ property + " as required.";
+				}
+			}
+			// defined special case
+			if ("concentration".equals(property)
+					&& ("g/L".equals(cu) || "mol/L".equals(cu)))
+				return null;
+
+			return "unit " + unit + " has the base units " + cu
+					+ ", and are not from the property " + property
+					+ " as required.";
+		} catch (UOMoRuntimeException e) {
+			return e.getMessage();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ohf.ucum.UcumServiceEx#validateCanonicalUnits(java.lang.String
+	 * , java.lang.String)
+	 */
+	public String validateCanonicalUnits(String unit, String canonical) {
+		assert checkStringParam(unit) : paramError("validate", "unit",
+				"must not be null or empty");
+		assert checkStringParam(canonical) : paramError(
+				"validateCanonicalUnits", "canonical",
+				"must not be null or empty");
+		try {
+			Term term = new ExpressionParser(model).parse(unit);
+			Canonical can = new UcumConverter(model, handlers).convert(term);
+			term = can.getUnit();
+			String cu = new ExpressionComposer().compose(term);
+			if (!canonical.equals(cu))
+				return "unit " + unit + " has the base units " + cu + ", not "
+						+ canonical + " as required.";
+			return null;
+		} catch (UOMoRuntimeException e) {
+			return e.getMessage();
+		}
+	}
+
+	/**
+	 * given a unit, return a formal description of what the units stand for
+	 * using full names
+	 * 
+	 * @param units
+	 *            the unit code
+	 * @return formal description
+	 * @throws UOMoRuntimeException
+	 */
+	public String analyse(String unit) throws UOMoRuntimeException {
+		assert checkStringParam(unit) : paramError("analyse", "unit",
+				"must not be null or empty");
+		Term term = new ExpressionParser(model).parse(unit);
+		return new FormalStructureComposer().compose(term);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ohf.ucum.UcumServiceEx#getCanonicalUnits(java.lang.String)
+	 */
+	public String getCanonicalUnits(String unit) throws UOMoRuntimeException {
+		assert checkStringParam(unit) : paramError("getCanonicalUnits", "unit",
+				"must not be null or empty");
+		try {
+			Term term = new ExpressionParser(model).parse(unit);
+			term = new UcumConverter(model, handlers).convert(term).getUnit();
+			return new ExpressionComposer().compose(term);
+		} catch (RuntimeException e) {
+			throw new UOMoRuntimeException("Error processing " + unit + ": "
+					+ e.getMessage(), e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.ucum.UcumServiceEx#getDefinedForms(java.lang.String)
+	 */
+	public List<DefinedUnit> getDefinedForms(String code)
+			throws UOMoRuntimeException {
+		assert checkStringParam(code) : paramError("getDefinedForms", "code",
+				"must not be null or empty");
+		List<DefinedUnit> result = new ArrayList<DefinedUnit>();
+		BaseUnit base = model.getBaseUnit(code);
+		if (base != null) {
+			for (DefinedUnit unit : model.getDefinedUnits()) {
+				if (!unit.isSpecial()
+						&& code.equals(getCanonicalUnits(unit.getCode())))
+					result.add(unit);
+			}
+		}
+		return result;
+	}
+
+	private boolean checkStringParam(String s) {
+		return s != null && !s.equals("");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ohf.ucum.UcumServiceEx#getCanonicalForm(org.eclipse.ohf.ucum
+	 * .UcumEssenceService.Pair)
+	 */
+	public Pair<Number, String> getCanonicalForm(Pair<Number, String> value)
+			throws UOMoRuntimeException {
+		assert value != null : paramError("getCanonicalForm", "value",
+				"must not be null");
+		assert checkStringParam(value.getCode()) : paramError(
+				"getCanonicalForm", "value.code", "must not be null or empty");
+
+		Term term = new ExpressionParser(model).parse(value.getCode());
+		Canonical c = new UcumConverter(model, handlers).convert(term);
+		if (value.getValue() == null)
+			return new Pair<Number, String>(null,
+					new ExpressionComposer().compose(c.getUnit()));
+		else
+			return new Pair<Number, String>(
+					((BigDecimal) value.getValue()).multiply(c.getValue()),
+					new ExpressionComposer().compose(c.getUnit()));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.uomo.ucum.UcumServiceEx#convert(java.math.BigDecimal,
+	 * java.lang.String, java.lang.String)
+	 */
+	public Number convert(final Number value, String sourceUnit, String destUnit)
+			throws UOMoRuntimeException {
+		assert value != null : paramError("convert", "value",
+				"must not be null");
+		assert checkStringParam(sourceUnit) : paramError("convert",
+				"sourceUnit", "must not be null or empty");
+		assert checkStringParam(destUnit) : paramError("convert", "destUnit",
+				"must not be null or empty");
+
+		if (sourceUnit.equals(destUnit))
+			return value;
+
+		Canonical src = new UcumConverter(model, handlers)
+				.convert(new ExpressionParser(model).parse(sourceUnit));
+		Canonical dst = new UcumConverter(model, handlers)
+				.convert(new ExpressionParser(model).parse(destUnit));
+		String s = new ExpressionComposer().compose(src.getUnit());
+		String d = new ExpressionComposer().compose(dst.getUnit());
+		if (!s.equals(d))
+			throw new UOMoRuntimeException("Unable to convert between units "
+					+ sourceUnit + " and " + destUnit
+					+ " as they do not have matching canonical forms (" + s
+					+ " and " + d + " respectively)");
+		final BigDecimal decValue = (BigDecimal) value;
+		BigDecimal canValue = decValue.multiply(src.getValue());
+		println(decValue.toPlainString() + sourceUnit + " =("
+				+ src.getValue().toPlainString() + ")= "
+				+ canValue.toPlainString() + s + " =("
+				+ dst.getValue().toPlainString() + ")= "
+				+ canValue.divide(dst.getValue()) + destUnit);
+		return canValue.divide(dst.getValue(), new MathContext(25));
+	}
+
+	public Pair<Number, String> multiply(Pair<Number, String> o1,
+			Pair<Number, String> o2) {
+		// Term term = new ExpressionParser(model).parse(o1.getCode());
+		// Canonical c = new Converter(model, handlers).convert(term);
+		return new Pair<Number, String>(
+				((BigDecimal) o1.getValue()).multiply((BigDecimal) o2
+						.getValue()),
+				// new ExpressionComposer().compose(c.getUnit()));
+				o1.getCode() + "." + o2.getCode());
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumValidator.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumValidator.java
new file mode 100644
index 0000000..7c058f1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/impl/UcumValidator.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - generic improvements
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.core.IListValidator;
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.ucum.expression.Term;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.model.UcumUnit;
+import org.eclipse.uomo.ucum.parsers.ExpressionComposer;
+import org.eclipse.uomo.ucum.parsers.ExpressionParser;
+import org.eclipse.uomo.util.Registry;
+
+/**
+ * @author Grahame Grieve
+ * @author Werner Keil
+ * @version 1.1 ($Revision: 306 $), $Date: 2013-03-08 $
+ */
+public class UcumValidator implements IListValidator<String> {
+
+	private final UcumModel model;
+	private final Registry<?> handlers;
+	private List<String> result;
+
+	public UcumValidator(UcumModel model, Registry<?> handlers) {
+		super();
+		this.model = model;
+		this.handlers = handlers;
+	}
+
+	public List<String> validate() {
+		result = new ArrayList<String>();
+		checkCodes();
+		checkUnits();
+		return result;
+	}
+
+	private void checkCodes() {
+		for (UcumUnit unit : model.getBaseUnits()) {
+			checkUnitCode(unit.getCode(), true);
+		}
+		for (UcumUnit unit : model.getDefinedUnits()) {
+			checkUnitCode(unit.getCode(), true);
+		}
+	}
+
+	private void checkUnits() {
+		for (DefinedUnit unit : model.getDefinedUnits()) {
+			if (!unit.isSpecial())
+				checkUnitCode(unit.getValue().getUnit(), false);
+			else if (!handlers.exists(unit.getCode()))
+				result.add("No Handler for " + unit.getCode().toString());
+		}
+	}
+
+	private void checkUnitCode(String code, boolean primary) {
+		try {
+			Term term = new ExpressionParser(model).parse(code);
+			String c = new ExpressionComposer().compose(term);
+			if (!c.equals(code))
+				result.add("Round trip failed: " + code + " -> " + c);
+			term = new UcumConverter(model, handlers).convert(term).getUnit();
+		} catch (UOMoRuntimeException e) {
+			result.add(code + ": " + e.getMessage());
+		}
+		if (primary)
+			try {
+				// there can't be any codes that have digits in them that aren't
+				// inside []
+				boolean inBrack = false;
+				boolean nonDigits = false;
+				for (int i = 0; i < code.length(); i++) {
+					char ch = code.charAt(i);
+					if (ch == '[')
+						if (inBrack)
+							throw new UOMoRuntimeException("nested [");
+						else
+							inBrack = true;
+					if (ch == ']')
+						if (!inBrack)
+							throw new UOMoRuntimeException("] without [");
+						else
+							inBrack = false;
+					nonDigits = nonDigits || !(ch >= '0' && ch <= '9');
+					if (ch >= '0' && ch <= '9' && !inBrack && nonDigits) {
+						throw new UOMoException(
+								"code "
+										+ code
+										+ " is ambiguous because  it has digits outside []");
+					}
+				}
+			} catch (UOMoException e) {
+				result.add(e.getMessage());
+			}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/Messages.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/Messages.java
new file mode 100644
index 0000000..43520d1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/Messages.java
@@ -0,0 +1,29 @@
+package org.eclipse.uomo.ucum.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+	public static String DefinitionParser_0;
+	public static String DefinitionParser_2;
+	public static String DefinitionParser_29;
+	public static String DefinitionParser_3;
+	public static String DefinitionParser_30;
+	public static String DefinitionParser_DateFormat;
+	public static String DefinitionParser_54;
+	public static String DefinitionParser_55;
+	public static String DefinitionParser_56;
+	public static String DefinitionParser_57;
+	public static String DefinitionParser_58;
+	public static String DefinitionParser_59;
+	public static String DefinitionParser_60;
+	public static String DefinitionParser_8;
+	public static String DefinitionParser_9;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/package-info.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/package-info.java
new file mode 100644
index 0000000..0963a5c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/internal/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author Werner Keil
+ *
+ */
+package org.eclipse.uomo.ucum.internal;
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/BaseUnit.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/BaseUnit.java
new file mode 100644
index 0000000..e5dc4d9
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/BaseUnit.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Refactoring and improvements
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.util.Map;
+
+import org.eclipse.uomo.units.impl.DimensionImpl;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * @author Werner Keil
+ * @version 1.1
+ */
+public class BaseUnit extends UcumUnit {
+
+
+	/**
+	 * abbrevation for property
+	 */
+	private char dim;
+	
+	/**
+	 * @param code
+	 * @param codeUC
+	 */
+	public BaseUnit(String code, String codeUC) {
+		super(ConceptKind.BASEUNIT, code, codeUC);
+	}
+
+	/**
+	 * @return the dim
+	 */
+	public char getDim() {
+		return dim;
+	}
+
+	/**
+	 * @param dim the dim to set
+	 */
+	public void setDim(char dim) {
+		this.dim = dim;
+	}
+
+	@Override
+	public Unit add(double arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit asType(Class arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit divide(Unit arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public UnitConverter getConverterTo(Unit arg0)
+			throws UnconvertibleException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public UnitConverter getConverterToAny(Unit arg0)
+			throws IncommensurableException, UnconvertibleException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Dimension getDimension() {
+		return DimensionImpl.valueOf(dim);
+	}
+
+	@Override
+	public Map getProductUnits() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit getSystemUnit() {
+		return this;
+	}
+
+	@Override
+	public Unit inverse() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit multiply(double arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit multiply(Unit arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit transform(UnitConverter arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Concept.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Concept.java
new file mode 100644
index 0000000..7cf7261
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Concept.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2012, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - updates and consolidation with core
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.core.ICode;
+import org.eclipse.uomo.core.IDescription;
+import org.eclipse.uomo.core.INames;
+import org.eclipse.uomo.core.ISymbol;
+
+public class Concept implements ICode, IDescription, ISymbol, INames {
+
+	private final ConceptKind kind;
+	/**
+	 * case sensitive code for this concept
+	 */
+	private String code;
+	
+	/**
+	 * case insensitive (UPPERCASE) code for this concept
+	 */
+	private String codeUC;
+	
+	/**
+	 * print symbol for this code 
+	 */
+	private String printSymbol;
+	
+	/**
+	 * names for the concept
+	 */
+	private List<String> names = new ArrayList<String>();
+	
+	
+	/**
+	 * @param code
+	 * @param codeUC
+	 */
+	public Concept(ConceptKind kind, String code, String codeUC) {
+		super();
+		this.kind = kind;
+		this.code = code;
+		this.codeUC = codeUC;
+	}
+
+	/**
+	 * @return the code
+	 */
+	public String getCode() {
+		return code;
+	}
+
+	/**
+	 * @param code the code to set
+	 */
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	/**
+	 * @return the codeUC
+	 */
+	public String getCodeUC() {
+		return codeUC;
+	}
+
+	/**
+	 * @param codeUC the codeUC to set
+	 */
+	public void setCodeUC(String codeUC) {
+		this.codeUC = codeUC;
+	}
+
+	/**
+	 * @return the printSymbol
+	 */
+	public String getPrintSymbol() {
+		return printSymbol;
+	}
+
+	/**
+	 * @param printSymbol the printSymbol to set
+	 */
+	public void setPrintSymbol(String printSymbol) {
+		this.printSymbol = printSymbol;
+	}
+	
+	@Override
+	public String getSymbol() {
+		return getPrintSymbol();
+	}
+
+	/**
+	 * @return the names
+	 */
+	public List<String> getNames() {
+		return names;
+	}
+
+	/**
+	 * @return the kind
+	 */
+	public ConceptKind getKind() {
+		return kind;
+	}
+
+	public String getDescription() {
+		return  kind.toString().toLowerCase()+" "+code+" ('"+names.get(0)+"')"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+	
+	@Override
+	public String toString() {
+		return this.getCode() + " = " + getDescription(); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/ConceptKind.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/ConceptKind.java
new file mode 100644
index 0000000..9d04b7f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/ConceptKind.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - added visible name
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import org.eclipse.uomo.core.IVisibleName;
+
+public enum ConceptKind implements IVisibleName {
+	PREFIX("prefix"),
+	BASEUNIT("base-unit"),
+	UNIT("unit");
+	
+	private final String visName;
+	
+	private ConceptKind(String vName) {
+		visName = vName;
+	}
+	
+	public String visibleName() {
+		return visName;
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/DefinedUnit.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/DefinedUnit.java
new file mode 100644
index 0000000..b4c9812
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/DefinedUnit.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2013, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Refactoring and improvements
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.util.Map;
+
+import org.eclipse.uomo.units.impl.DimensionImpl;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * @author Werner Keil
+ * @version 1.1
+ */
+public class DefinedUnit extends UcumUnit {
+
+	/**
+	 * whether this is a metric unit or not
+	 */
+	private boolean metric;
+
+	/**
+	 * special means?
+	 */
+	private boolean isSpecial;
+
+	/**
+	 * The class of this unit
+	 */
+	private String class_;
+
+	/**
+	 * Value details
+	 */
+	private Value<?> value;
+
+	/**
+	 * @param code
+	 * @param codeUC
+	 */
+	public DefinedUnit(String code, String codeUC) {
+		super(ConceptKind.UNIT, code, codeUC);
+	}
+
+	/**
+	 * @return the metric
+	 */
+	public boolean isMetric() {
+		return metric;
+	}
+
+	/**
+	 * @param metric
+	 *            the metric to set
+	 */
+	public void setMetric(boolean metric) {
+		this.metric = metric;
+	}
+
+	/**
+	 * @return the isSpecial
+	 */
+	public boolean isSpecial() {
+		return isSpecial;
+	}
+
+	/**
+	 * @param isSpecial
+	 *            the isSpecial to set
+	 */
+	public void setSpecial(boolean isSpecial) {
+		this.isSpecial = isSpecial;
+	}
+
+	/**
+	 * @return the class_
+	 */
+	public String getClass_() {
+		return class_;
+	}
+
+	/**
+	 * @param class_
+	 *            the class_ to set
+	 */
+	public void setClass_(String class_) {
+		this.class_ = class_;
+	}
+
+	/**
+	 * @return the value
+	 */
+	public Value<?> getValue() {
+		return value;
+	}
+
+	/**
+	 * @param value
+	 *            the value to set
+	 */
+	public void setValue(Value<?> value) {
+		this.value = value;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ohf.ucum.model.BaseUnit#getDescription()
+	 */
+	@Override
+	public String getDescription() {
+		return super.getDescription() + " = " + value.getDescription();
+	}
+
+	@Override
+	public Unit add(double arg0) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Unit alternate(String arg0) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Unit asType(Class arg0) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Unit divide(Unit arg0) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public UnitConverter getConverterTo(Unit arg0)
+			throws UnconvertibleException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public UnitConverter getConverterToAny(Unit arg0)
+			throws IncommensurableException, UnconvertibleException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Dimension getDimension() {
+		return DimensionImpl.NONE;
+	}
+
+	@Override
+	public Map getProductUnits() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit getSystemUnit() {
+		return (metric ? this : null);
+	}
+
+	@Override
+	public Unit inverse() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit multiply(double arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit multiply(Unit arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Unit transform(UnitConverter arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Prefix.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Prefix.java
new file mode 100644
index 0000000..e6619ff
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Prefix.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.math.BigDecimal;
+
+public class Prefix extends Concept {
+	
+	/**
+	 * value for the prefix.  
+	 */
+	private BigDecimal value; // 1^-24 through to 1^24
+
+	/**
+	 * @param code
+	 * @param codeUC
+	 */
+	public Prefix(String code, String codeUC) {
+		super(ConceptKind.PREFIX, code, codeUC);
+	}
+
+	/**
+	 * @return the index
+	 */
+	public Number getValue() {
+		return value;
+	}
+
+	/**
+	 * @param index the index to set
+	 */
+	public void setValue(BigDecimal index) {
+		this.value = index;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.ucum.model.Concept#getDescription()
+	 */
+	@Override
+	public String getDescription() {
+		return super.getDescription()+" = "+value.toEngineeringString();
+	}
+	
+	
+	
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumModel.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumModel.java
new file mode 100644
index 0000000..36b0fa9
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumModel.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2012, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Enhanced and unified with other UOMo parts 
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.uomo.core.IName;
+
+public class UcumModel implements IName {
+
+	/**
+	 * version="1.7" 
+	 */
+	private final String version;
+	
+	/**
+	 * revision="$Revision: 1.1 $"
+	 */
+	private final String revision;
+	
+	/**
+	 * date this revision was made public
+	 */
+	private final Date revisionDate;
+	
+	private final List<Prefix> prefixes = new ArrayList<Prefix>();
+	private final List<BaseUnit> baseUnits = new ArrayList<BaseUnit>();
+	private final List<DefinedUnit> definedUnits = new ArrayList<DefinedUnit>();
+
+	
+	/**
+	 * @param revision
+	 * @param revisionDate
+	 */
+	public UcumModel(String version, String revision, Date revisionDate) {
+		super();
+		this.version = version;
+		this.revision = revision;
+		this.revisionDate = revisionDate;
+	}
+	
+	public String getName() {
+		return "UCUM";
+	}
+	/**
+	 * @return the prefixes
+	 */
+	public List<Prefix> getPrefixes() {
+		return prefixes;
+	}
+	/**
+	 * @return the baseUnits
+	 */
+	public List<BaseUnit> getBaseUnits() {
+		return baseUnits;
+	}
+	/**
+	 * @return the units
+	 */
+	public List<DefinedUnit> getDefinedUnits() {
+		return definedUnits;
+	}
+	/**
+	 * @return the revision
+	 */
+	public String getRevision() {
+		return revision;
+	}
+//	/**
+//	 * @param revision the revision to set
+//	 */
+//	public void setRevision(String revision) {
+//		this.revision = revision;
+//	}
+	/**
+	 * @return the revisionDate
+	 */
+	public Date getRevisionDate() {
+		return revisionDate;
+	}
+//	/**
+//	 * @param revisionDate the revisionDate to set
+//	 */
+//	public void setRevisionDate(Date revisionDate) {
+//		this.revisionDate = revisionDate;
+//	}
+	/**
+	 * @return the version
+	 */
+	public String getVersion() {
+		return version;
+	}
+//	/**
+//	 * @param version the version to set
+//	 */
+//	public void setVersion(String version) {
+//		this.version = version;
+//	}
+	
+	public UcumUnit getUnit(String code) {
+		for (UcumUnit unit : getBaseUnits()) {
+			if (unit.getCode().equals(code))
+				return unit;
+		}
+		for (UcumUnit unit : getDefinedUnits()) {
+			if (unit.getCode().equals(code))
+				return unit;
+		}
+		return null;
+	}
+	
+	public BaseUnit getBaseUnit(String code) {
+		for (BaseUnit unit : getBaseUnits()) {
+			if (unit.getCode().equals(code))
+				return unit;
+		}
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumUnit.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumUnit.java
new file mode 100644
index 0000000..0931fb9
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/UcumUnit.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2013, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Refactoring and improvements
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * @author Werner Keil
+ * @version 1.1
+ */
+@SuppressWarnings("rawtypes")
+public abstract class UcumUnit extends Concept implements Unit {
+	
+	/**
+	 * Holds the dimensionless unit <code>ONE</code>.
+	 */
+	public static final UcumUnit ONE = new DefinedUnit("", "");
+	
+	/**
+	 * kind of thing this base unit represents
+	 */
+	private String property;
+
+	protected UcumUnit(ConceptKind kind, String code, String codeUC) {
+		super(kind, code, codeUC);
+	}
+
+	/**
+	 * @return the property
+	 */
+	public String getProperty() {
+		return property;
+	}
+
+	/**
+	 * @param property the property to set
+	 */
+	public void setProperty(String property) {
+		this.property = property;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.ucum.model.Concept#getDescription()
+	 */
+	@Override
+	public String getDescription() {
+		return super.getDescription()+" ("+property+")";
+	}
+	
+	@Override
+	public Unit<?> alternate(String a) {
+		return this;
+	}
+	
+	@Override
+	public Unit<?> divide(double divisor) {
+		if (divisor == 1)
+			return this;
+		return null;
+	}
+	
+	@Override
+	public boolean isCompatible(Unit u) {
+		return u.getDimension() != null && u.getDimension().equals(getDimension());
+	}
+	
+	/**
+	 * Returns a unit equals to this unit raised to an exponent.
+	 * 
+	 * @param n
+	 *            the exponent.
+	 * @return the result of raising this unit to the exponent.
+	 */
+	public final Unit<?> pow(int n) {
+		if (n > 0)
+			return this.multiply(this.pow(n - 1));
+		else if (n == 0)
+			return ONE;
+		else
+			// n < 0
+			return ONE.divide(this.pow(-n));
+	}
+
+	@Override
+	public Unit<?> root(int n) {
+		if (n == 0)
+			throw new ArithmeticException("Root's order of zero"); //$NON-NLS-1$
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Value.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Value.java
new file mode 100644
index 0000000..c7f492d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/model/Value.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Cleaning, unification with other UOMo parts and Unit-API
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.model;
+
+import java.math.BigDecimal;
+
+import org.eclipse.uomo.core.IDescription;
+import org.eclipse.uomo.core.IText;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+public class Value<Q extends Quantity<Q>> implements Quantity<Q>, IDescription, IText {
+	// TODO should use Quantity
+	// TODO make this a "real" unit, should be at least UcumUnit
+	private String unit;
+	private Unit<Q> realUnit;
+	private String unitUC;
+	
+	private BigDecimal value;
+	
+	private String text;
+
+	/**
+	 * @param unit
+	 * @param unitUC
+	 * @param value
+	 */
+	public Value(String unit, String unitUC, BigDecimal value) {
+		super();
+		this.unit = unit;
+		this.unitUC = unitUC;
+		this.value = value;
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public String getUnit() {
+		return unit;
+	}
+
+	/**
+	 * @param unit the unit to set
+	 */
+	public void setUnit(String unit) {
+		this.unit = unit;
+	}
+
+	/**
+	 * @return the unitUC
+	 * @deprecated currently not used
+	 */
+	public String getUnitUC() {
+		return unitUC;
+	}
+
+	/**
+	 * @param unitUC the unitUC to set
+	 * @deprecated currently not used
+	 */
+	public void setUnitUC(String unitUC) {
+		this.unitUC = unitUC;
+	}
+
+	/**
+	 * @param value the value to set
+	 * @deprecated
+	 */
+	void setValue(BigDecimal value) {
+		this.value = value;
+	}
+
+	/**
+	 * @return the text
+	 */
+	public String getText() {
+		return text;
+	}
+
+	/**
+	 * @param text the text to set
+	 */
+	public void setText(String text) {
+		this.text = text;
+	}
+
+	public String getDescription() {
+		if (value == null)
+			return unit;
+		return value.toEngineeringString()+unit;
+	}
+
+	public Number value() {
+		return value;
+	}
+
+	public Unit<Q> unit() {
+		return realUnit;
+	}		
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/DefinitionParser.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/DefinitionParser.java
new file mode 100644
index 0000000..4cea16d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/DefinitionParser.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2012, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - added static imports
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+import static org.eclipse.uomo.ucum.model.ConceptKind.*;
+import static org.xmlpull.v1.XmlPullParser.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.util.Date;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.ucum.internal.Messages;
+import org.eclipse.uomo.ucum.model.BaseUnit;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.Prefix;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.model.Value;
+import org.eclipse.uomo.util.Parser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.SimpleDateFormat;
+
+
+/**
+ * Parses the file ucum-essense.xml
+ * 
+ * @author Grahame Grieve
+ * @author Werner Keil
+ */
+
+public class DefinitionParser implements Parser<String, UcumModel> {
+
+	public UcumModel parse(String filename) throws UOMoException {
+		try {
+			return parse(new FileInputStream(new File(filename)));
+		} catch (XmlPullParserException x) {
+			throw new UOMoException(x);
+		}  catch (ParseException p) {
+			throw new UOMoException(p);
+		}  catch (IOException i) {
+			throw new UOMoException(i);
+		}
+	}
+	
+	public UcumModel parse(InputStream stream) throws XmlPullParserException, IOException, ParseException {
+		XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
+				System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
+		factory.setNamespaceAware(true);
+		XmlPullParser xpp = factory.newPullParser();
+
+		xpp.setInput(stream, null);
+		
+        int eventType = xpp.next();
+        if (eventType != START_TAG)
+        	throw new XmlPullParserException(Messages.DefinitionParser_0);
+        if (!xpp.getName().equals("root"))  //$NON-NLS-1$
+        	throw new XmlPullParserException(Messages.DefinitionParser_2+xpp.getName()+Messages.DefinitionParser_3);
+        final DateFormat fmt = new SimpleDateFormat(Messages.DefinitionParser_DateFormat);
+        Date date = fmt.parse(xpp.getAttributeValue(null, "revision-date").substring(7, 32));         //$NON-NLS-1$
+		UcumModel root = new UcumModel(xpp.getAttributeValue(null, "version"), xpp.getAttributeValue(null, "revision"), date); //$NON-NLS-1$ //$NON-NLS-2$
+        xpp.next();
+		while (xpp.getEventType() != END_TAG) {
+			if (xpp.getEventType() == TEXT) {
+				if (StringUtils.isWhitespace(xpp.getText()))
+					xpp.next();
+				else
+					throw new XmlPullParserException(Messages.DefinitionParser_8+xpp.getText());
+			} else if (xpp.getName().equals(PREFIX.visibleName())) 
+				root.getPrefixes().add(parsePrefix(xpp));
+			else if (xpp.getName().equals(BASEUNIT.visibleName())) 
+				root.getBaseUnits().add(parseBaseUnit(xpp));
+			else if (xpp.getName().equals(UNIT.visibleName())) 
+				root.getDefinedUnits().add(parseUnit(xpp));
+			else 
+				throw new XmlPullParserException(Messages.DefinitionParser_9+xpp.getName());
+		}
+		return root;
+	}
+
+	private DefinedUnit parseUnit(XmlPullParser xpp) throws XmlPullParserException, IOException {
+		DefinedUnit unit = new DefinedUnit(xpp.getAttributeValue(null, "Code"), xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ //$NON-NLS-2$
+		unit.setMetric("yes".equals(xpp.getAttributeValue(null, "isMetric"))); //$NON-NLS-1$ //$NON-NLS-2$
+		unit.setSpecial("yes".equals(xpp.getAttributeValue(null, "isSpecial"))); //$NON-NLS-1$ //$NON-NLS-2$
+		unit.setClass_(xpp.getAttributeValue(null, "class")); //$NON-NLS-1$
+		xpp.next();
+		skipWhitespace(xpp);
+		while (xpp.getEventType() == START_TAG && "name".equals(xpp.getName())) //$NON-NLS-1$
+			unit.getNames().add(readElement(xpp, "name", UNIT.visibleName()+" "+unit.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		if (xpp.getEventType() == START_TAG && "printSymbol".equals(xpp.getName())) //$NON-NLS-1$
+			unit.setPrintSymbol(readElement(xpp, "printSymbol", UNIT.visibleName()+" "+unit.getCode(), true)); //$NON-NLS-1$ //$NON-NLS-2$
+		unit.setProperty(readElement(xpp, "property", UNIT.visibleName()+" "+unit.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		unit.setValue(parseValue(xpp, "unit "+unit.getCode())); //$NON-NLS-1$
+		xpp.next();
+		skipWhitespace(xpp);
+		return unit;
+	}
+
+	private Value<?> parseValue(XmlPullParser xpp, String context) throws XmlPullParserException, IOException {
+		checkAtElement(xpp, "value", context); //$NON-NLS-1$
+		BigDecimal val = null;
+		if (xpp.getAttributeValue(null, "value") != null)  //$NON-NLS-1$
+		try {
+			val = new BigDecimal(xpp.getAttributeValue(null, "value")); //$NON-NLS-1$
+		} catch (NumberFormatException e) {
+			throw new XmlPullParserException(Messages.DefinitionParser_29+context+Messages.DefinitionParser_30+e.getMessage());
+		}
+		@SuppressWarnings("rawtypes")
+		Value<?> value = new Value(xpp.getAttributeValue(null, "Unit"), xpp.getAttributeValue(null, "UNIT"), val); //$NON-NLS-1$ //$NON-NLS-2$
+		value.setText(readElement(xpp, "value", context, true)); //$NON-NLS-1$
+		return value;
+	}
+
+	private BaseUnit parseBaseUnit(XmlPullParser xpp) throws XmlPullParserException, IOException {
+		BaseUnit base = new BaseUnit(xpp.getAttributeValue(null, "Code"), xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ //$NON-NLS-2$
+		base.setDim(xpp.getAttributeValue(null, "dim").charAt(0)); //$NON-NLS-1$
+		xpp.next();
+		skipWhitespace(xpp);
+		base.getNames().add(readElement(xpp, "name", BASEUNIT.visibleName()+" "+base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		base.setPrintSymbol(readElement(xpp, "printSymbol", BASEUNIT.visibleName()+" "+base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		base.setProperty(readElement(xpp, "property", BASEUNIT.visibleName()+" "+base.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		xpp.next();
+		skipWhitespace(xpp);
+		return base;
+	}
+
+	private Prefix parsePrefix(XmlPullParser xpp) throws XmlPullParserException, IOException {
+		Prefix prefix = new Prefix(xpp.getAttributeValue(null, "Code"), xpp.getAttributeValue(null, "CODE")); //$NON-NLS-1$ //$NON-NLS-2$
+		xpp.next();
+		skipWhitespace(xpp);
+		prefix.getNames().add(readElement(xpp, "name", PREFIX.visibleName()+" "+prefix.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		prefix.setPrintSymbol(readElement(xpp, "printSymbol", PREFIX.visibleName()+" "+prefix.getCode(), false)); //$NON-NLS-1$ //$NON-NLS-2$
+		checkAtElement(xpp, "value", PREFIX.visibleName()+" "+prefix.getCode()); //$NON-NLS-1$ //$NON-NLS-2$
+		prefix.setValue(new BigDecimal(xpp.getAttributeValue(null, "value"))); //$NON-NLS-1$
+		readElement(xpp, "value", PREFIX.visibleName()+" "+prefix.getCode(), true); //$NON-NLS-1$ //$NON-NLS-2$
+		xpp.next();
+		skipWhitespace(xpp);
+		return prefix;
+	}
+
+	private String readElement(XmlPullParser xpp, String name, String context, boolean complex) throws XmlPullParserException, IOException {
+		checkAtElement(xpp, name, context);
+		xpp.next();
+		skipWhitespace(xpp);
+		String val = null;
+		if (complex) {
+			val = readText(xpp);
+		} else if (xpp.getEventType() == TEXT) {
+			val = xpp.getText();
+			xpp.next();
+			skipWhitespace(xpp);
+		}
+		if (xpp.getEventType() != END_TAG) {
+			throw new XmlPullParserException(Messages.DefinitionParser_54+context);
+		}
+		xpp.next();
+		skipWhitespace(xpp);
+		return val;
+	}
+
+	private String readText(XmlPullParser xpp) throws XmlPullParserException, IOException {
+		StringBuilder bldr = new StringBuilder();
+		while (xpp.getEventType() != END_TAG) {
+			if (xpp.getEventType() == TEXT) {
+				bldr.append(xpp.getText());
+				xpp.next();
+			} else {
+				xpp.next();
+				bldr.append(readText(xpp));
+				xpp.next();
+				skipWhitespace(xpp);
+			}
+		}
+		return bldr.toString();
+	}
+
+	private void skipWhitespace(XmlPullParser xpp) throws XmlPullParserException, IOException {
+		while (xpp.getEventType() == TEXT && StringUtils.isWhitespace(xpp.getText())) 
+			xpp.next();		
+	}
+
+	private void checkAtElement(XmlPullParser xpp, String name, String context) throws XmlPullParserException {
+		if (xpp.getEventType() != START_TAG)
+			throw new XmlPullParserException(Messages.DefinitionParser_55+name+Messages.DefinitionParser_56+Integer.toString(xpp.getEventType())+Messages.DefinitionParser_57+context);
+		if (!xpp.getName().equals(name))
+			throw new XmlPullParserException(Messages.DefinitionParser_58+name+Messages.DefinitionParser_59+xpp.getName()+Messages.DefinitionParser_60+context);		
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionComposer.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionComposer.java
new file mode 100644
index 0000000..212901c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionComposer.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+import org.eclipse.uomo.ucum.expression.Component;
+import org.eclipse.uomo.ucum.expression.Factor;
+import org.eclipse.uomo.ucum.expression.Operator;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+
+public class ExpressionComposer {
+
+
+	public String compose(Term term) {
+		if (term == null)
+			return "1";
+		StringBuilder bldr = new StringBuilder();
+		composeTerm(bldr, term);
+		return bldr.toString();
+	}
+
+	private void composeTerm(StringBuilder bldr, Term term) {
+		if (term.getComp() != null)
+			composeComp(bldr, term.getComp());
+		if (term.getOp() != null)
+			composeOp(bldr, term.getOp());
+		if (term.getTerm() != null) { 
+			composeTerm(bldr, term.getTerm());		
+		}
+	}
+
+	private void composeComp(StringBuilder bldr, Component comp) {
+		if (comp instanceof Factor)
+			composeFactor(bldr, (Factor)comp);
+		else if (comp instanceof Symbol)
+			composeSymbol(bldr, (Symbol)comp);
+		else if (comp instanceof Term) {
+			bldr.append('(');
+			composeTerm(bldr, (Term)comp);
+			bldr.append(')');
+		} else
+			bldr.append('?');
+	}
+
+	private void composeSymbol(StringBuilder bldr, Symbol symbol) {
+		if (symbol.getPrefix() != null) { 
+			bldr.append(symbol.getPrefix().getCode());
+		}
+		bldr.append(symbol.getUnit().getCode());
+		if (symbol.getExponent() != 1) { 
+			bldr.append(symbol.getExponent());
+		}
+	}
+
+	private void composeFactor(StringBuilder bldr, Factor comp) {
+	   bldr.append(comp.getValue());		
+	}
+
+	private void composeOp(StringBuilder bldr, Operator op) {
+		if (op == Operator.DIVISION)
+			bldr.append("/");
+		else
+			bldr.append(".");
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionParser.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionParser.java
new file mode 100644
index 0000000..440015b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/ExpressionParser.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2013, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - Refactoring and improvement
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+import org.eclipse.uomo.core.UOMoRuntimeException;
+import org.eclipse.uomo.ucum.expression.Component;
+import org.eclipse.uomo.ucum.expression.Factor;
+import org.eclipse.uomo.ucum.expression.Operator;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+import org.eclipse.uomo.ucum.model.ConceptKind;
+import org.eclipse.uomo.ucum.model.DefinedUnit;
+import org.eclipse.uomo.ucum.model.Prefix;
+import org.eclipse.uomo.ucum.model.UcumModel;
+import org.eclipse.uomo.ucum.model.UcumUnit;
+import org.eclipse.uomo.util.Parser;
+
+public class ExpressionParser implements Parser<String, Term> {
+
+	private final UcumModel model;
+
+	/**
+	 * @param model
+	 */
+	public ExpressionParser(UcumModel model) {
+		super();
+		this.model = model;
+	}
+
+	public Term parse(String code) throws UOMoRuntimeException {
+		Lexer lexer = new Lexer(code);
+		return parseTerm(lexer, true);
+	}
+
+	private Term parseTerm(Lexer lexer, boolean first)
+			throws UOMoRuntimeException {
+		Term res = new Term();
+		if (first && lexer.getType() == TokenType.NONE) {
+			res.setComp(new Factor(1));
+		} else if (lexer.getType() == TokenType.SOLIDUS) {
+			res.setOp(Operator.DIVISION);
+			lexer.consume();
+			res.setTerm(parseTerm(lexer, false));
+		} else {
+			res.setComp(parseComp(lexer));
+			if (lexer.getType() != TokenType.NONE) {
+				if (lexer.getType() == TokenType.SOLIDUS)
+					res.setOp(Operator.DIVISION);
+				else if (lexer.getType() == TokenType.PERIOD)
+					res.setOp(Operator.MULTIPLICATION);
+				else
+					lexer.error("Expected '/' or '.'");
+				lexer.consume();
+				res.setTerm(parseTerm(lexer, false));
+			}
+		}
+		return res;
+	}
+
+	private Component parseComp(Lexer lexer) throws UOMoRuntimeException {
+		if (lexer.getType() == TokenType.NUMBER) {
+			Factor fact = new Factor(lexer.getTokenAsInt());
+			lexer.consume();
+			return fact;
+		} else if (lexer.getType() == TokenType.SYMBOL)
+			return parseSymbol(lexer);
+		else if (lexer.getType() == TokenType.NONE)
+			lexer.error("unexpected end of expression looking for a symbol or a number");
+		else
+			lexer.error("unexpected token looking for a symbol or a number");
+		return null; // we never get to here
+	}
+
+	private Component parseSymbol(Lexer lexer) throws UOMoRuntimeException {
+		Symbol symbol = new Symbol();
+		String sym = lexer.getToken();
+
+		// now, can we pick a prefix that leaves behind a metric unit?
+		Prefix selected = null;
+		UcumUnit unit = null;
+		for (Prefix prefix : model.getPrefixes()) {
+			if (sym.startsWith(prefix.getCode())) {
+				unit = model.getUnit(sym.substring(prefix.getCode().length()));
+				if (unit != null
+						&& (unit.getKind() == ConceptKind.BASEUNIT || ((DefinedUnit) unit)
+								.isMetric())) {
+					selected = prefix;
+					break;
+				}
+				;
+			}
+		}
+
+		if (selected != null) {
+			symbol.setPrefix(selected);
+			symbol.setUnit(unit);
+		} else {
+			unit = model.getUnit(sym);
+			if (unit != null)
+				symbol.setUnit(unit);
+			else if (!sym.equals("1"))
+				lexer.error("The unit '" + sym + "' is unknown");
+		}
+
+		lexer.consume();
+		if (lexer.getType() == TokenType.NUMBER) {
+			symbol.setExponent(lexer.getTokenAsInt());
+			lexer.consume();
+		} else
+			symbol.setExponent(1);
+
+		return symbol;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/FormalStructureComposer.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/FormalStructureComposer.java
new file mode 100644
index 0000000..6c56b49
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/FormalStructureComposer.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+import org.eclipse.uomo.ucum.expression.Component;
+import org.eclipse.uomo.ucum.expression.Factor;
+import org.eclipse.uomo.ucum.expression.Operator;
+import org.eclipse.uomo.ucum.expression.Symbol;
+import org.eclipse.uomo.ucum.expression.Term;
+
+public class FormalStructureComposer {
+
+	public String compose(Term term) {
+		StringBuilder bldr = new StringBuilder();
+		composeTerm(bldr, term);
+		return bldr.toString();
+	}
+
+	private void composeTerm(StringBuilder bldr, Term term) {
+		if (term.getComp() != null)
+			composeComp(bldr, term.getComp());
+		if (term.getOp() != null)
+			composeOp(bldr, term.getOp());
+		if (term.getTerm() != null) { 
+//			bldr.append('(');
+			composeTerm(bldr, term.getTerm());		
+//			bldr.append('}');
+		}
+	}
+
+	private void composeComp(StringBuilder bldr, Component comp) {
+		if (comp instanceof Factor)
+			composeFactor(bldr, (Factor)comp);
+		else if (comp instanceof Symbol)
+			composeSymbol(bldr, (Symbol)comp);
+		else if (comp instanceof Term)
+			composeTerm(bldr, (Term)comp);
+		else
+			bldr.append('?');
+	}
+
+	private void composeSymbol(StringBuilder bldr, Symbol symbol) {
+		bldr.append('(');
+		if (symbol.getPrefix() != null) { 
+			bldr.append(symbol.getPrefix().getNames().get(0));
+		}
+		bldr.append(symbol.getUnit().getNames().get(0));
+		if (symbol.getExponent() != 1) { 
+			bldr.append(" ^ ");
+			bldr.append(symbol.getExponent());
+		}
+		bldr.append(')');
+	}
+
+	private void composeFactor(StringBuilder bldr, Factor comp) {
+	   bldr.append(comp.getValue());		
+	}
+
+	private void composeOp(StringBuilder bldr, Operator op) {
+		if (op == Operator.DIVISION)
+			bldr.append(" / ");
+		else
+			bldr.append(" * ");
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/Lexer.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/Lexer.java
new file mode 100644
index 0000000..eb032bc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/Lexer.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2010, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+import org.eclipse.uomo.core.UOMoRuntimeException;
+
+public class Lexer {
+
+	private static final char NO_CHAR = Character.UNASSIGNED;
+	private String source;
+	private int index;
+
+	private String token;
+	private TokenType type;
+	private int start;
+
+	/**
+	 * @param source
+	 * @throws UOMoRuntimeException
+	 */
+	public Lexer(String source) throws UOMoRuntimeException {
+		super();
+		this.source = source;
+		if (source == null)
+			source = "";
+		index = 0;
+		consume();
+	}
+
+	public void consume() throws UOMoRuntimeException {
+		token = null;
+		type = TokenType.NONE;
+		start = index;
+		if (index < source.length()) {
+			char ch = nextChar();
+			if (!(checkSingle(ch, '/', TokenType.SOLIDUS)
+					|| checkSingle(ch, '.', TokenType.PERIOD)
+					|| checkSingle(ch, '(', TokenType.OPEN)
+					|| checkSingle(ch, ')', TokenType.CLOSE)
+					|| checkAnnotation(ch) || checkNumber(ch) || checkNumberOrSymbol(ch)))
+				throw new UOMoRuntimeException("Error processing unit '"
+						+ source + "': unexpected character '" + ch
+						+ "' at position " + Integer.toString(start));
+		}
+	}
+
+	private boolean checkNumber(char ch) throws UOMoRuntimeException {
+		if (ch == '+' || ch == '-') {
+			token = String.valueOf(ch);
+			ch = peekChar();
+			while ((ch >= '0' && ch <= '9')) {
+				token = token + ch;
+				index++;
+				ch = peekChar();
+			}
+			if (token.length() == 1) {
+				throw new UOMoRuntimeException("Error processing unit'"
+						+ source + "': unexpected character '" + ch
+						+ "' at position " + Integer.toString(start)
+						+ ": a + or - must be followed by at least one digit");
+			}
+			type = TokenType.NUMBER;
+			return true;
+		} else
+			return false;
+	}
+
+	private boolean checkNumberOrSymbol(char ch) throws UOMoRuntimeException {
+		boolean isSymbol = false;
+		boolean inBrackets = false;
+		if (isValidSymbolChar(ch, true)) {
+			token = String.valueOf(ch);
+			isSymbol = isSymbol || !((ch >= '0' && ch <= '9'));
+			inBrackets = checkBrackets(ch, inBrackets);
+			ch = peekChar();
+			inBrackets = checkBrackets(ch, inBrackets);
+			while (isValidSymbolChar(ch, !isSymbol || inBrackets)) {
+				token = token + ch;
+				isSymbol = isSymbol
+						|| ((ch != NO_CHAR) && !((ch >= '0' && ch <= '9')));
+				index++;
+				ch = peekChar();
+				inBrackets = checkBrackets(ch, inBrackets);
+			}
+			if (isSymbol)
+				type = TokenType.SYMBOL;
+			else
+				type = TokenType.NUMBER;
+			return true;
+		} else
+			return false;
+	}
+
+	private boolean checkBrackets(char ch, boolean inBrackets)
+			throws UOMoRuntimeException {
+		if (ch == '[')
+			if (inBrackets)
+				error("Nested [");
+			else
+				return true;
+		if (ch == ']')
+			if (!inBrackets)
+				error("] without [");
+			else
+				return false;
+		return inBrackets;
+	}
+
+	private boolean isValidSymbolChar(char ch, boolean allowDigits) {
+		return (allowDigits && ch >= '0' && ch <= '9')
+				|| (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
+				|| ch == '[' || ch == ']' || ch == '%' || ch == '*'
+				|| ch == '^' || ch == '\'' || ch == '"' || ch == '_';
+	}
+
+	private boolean checkAnnotation(char ch) throws UOMoRuntimeException {
+		if (ch == '{') {
+			while (ch != '}') {
+				ch = nextChar();
+				if (ch == 0)
+					throw new UOMoRuntimeException("Error processing unit'"
+							+ source + "': unterminated annotation");
+			}
+			// got to the end of the annotation - need to do it again
+			consume();
+			return true;
+		} else
+			return false;
+	}
+
+	private boolean checkSingle(char ch, char test, TokenType type) {
+		if (ch == test) {
+			token = String.valueOf(ch);
+			this.type = type;
+			return true;
+		}
+		return false;
+	}
+
+	private char nextChar() {
+		char res = index < source.length() ? source.charAt(index) : NO_CHAR;
+		index++;
+		return res;
+	}
+
+	private char peekChar() {
+		return index < source.length() ? source.charAt(index) : NO_CHAR;
+	}
+
+	/**
+	 * @return the token
+	 */
+	public String getToken() {
+		return token;
+	}
+
+	/**
+	 * @return the type
+	 */
+	public TokenType getType() {
+		return type;
+	}
+
+	public void error(String errMsg) throws UOMoRuntimeException {
+		throw new UOMoRuntimeException("Error processing unit '" + source
+				+ "': " + errMsg + "' at position " + Integer.toString(start));
+
+	}
+
+	public int getTokenAsInt() {
+		return token.charAt(0) == '+' ? Integer.parseInt(token.substring(1))
+				: Integer.parseInt(token);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/TokenType.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/TokenType.java
new file mode 100644
index 0000000..b33dd1e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/parsers/TokenType.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.parsers;
+
+public enum TokenType {
+	NONE,
+	NUMBER,
+	SYMBOL,
+	SOLIDUS,
+	PERIOD,
+	OPEN,
+	CLOSE;
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/CelsiusHandler.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/CelsiusHandler.java
new file mode 100644
index 0000000..152803d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/CelsiusHandler.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - adjusted to Unit-API
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.special;
+
+import java.math.BigDecimal;
+
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.unit.Unit;
+
+public class CelsiusHandler extends SpecialUnitHandler<Temperature> {
+
+	@Override
+	public String getCode() {
+		return "Cel";
+	}
+
+	@Override
+	public String getUnits() {
+		return "K";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.unitsofmeasurement.quantity.Quantity#unit()
+	 */
+	@Override
+	public Unit<Temperature> unit() {
+		return SI.KELVIN;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.unitsofmeasurement.quantity.Quantity#value()
+	 */
+	@Override
+	public BigDecimal value() {
+		return new BigDecimal(1);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/FahrenheitHandler.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/FahrenheitHandler.java
new file mode 100644
index 0000000..352e88d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/FahrenheitHandler.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * Copyright (c) 2010, 2013 Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - adjusted to Unit-API
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.special;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.unit.Unit;
+
+public class FahrenheitHandler extends SpecialUnitHandler<Temperature> {
+
+	@Override
+	public String getCode() {
+		return "[degF]";
+	}
+
+	@Override
+	public String getUnits() {
+		return "K";
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.unitsofmeasurement.quantity.Quantity#unit()
+	 */
+	@Override
+	public Unit<Temperature> unit() {
+		return SI.KELVIN;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.unitsofmeasurement.quantity.Quantity#value()
+	 */
+	@Override
+	public BigDecimal value() {		
+		return new BigDecimal(5).divide(new BigDecimal(9), new MathContext(20));
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/HoldingHandler.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/HoldingHandler.java
new file mode 100644
index 0000000..1e86282
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/HoldingHandler.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2008, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.special;
+
+import java.math.BigDecimal;
+
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * If you want to actually use one of these units, then you'll
+ * have to figure out how to implement them
+ * 
+ * @author Grahame Grieve
+ * @param <Q>
+ *
+ */
+public class HoldingHandler<Q extends Quantity<Q>> extends SpecialUnitHandler<Q> {
+
+	private final String code;
+	private final String units;
+	private BigDecimal value = BigDecimal.ONE;
+	@SuppressWarnings("unchecked")
+	private Unit<Q> unit = (Unit<Q>) AbstractUnit.ONE;
+	
+	/**
+	 * @param code
+	 * @param units
+	 */
+	public HoldingHandler(String code, String units) {
+		super();
+		this.code = code;
+		this.units = units;
+	}
+
+	public HoldingHandler(String code, String units, BigDecimal value) {
+		super();
+		this.code = code;
+		this.units = units;
+		this.value = value;
+	}
+	
+	public HoldingHandler(String code, Unit<Q> unit, BigDecimal value) {
+		super();
+		this.code = code;
+		this.unit = unit;
+		this.units = unit.getSymbol();
+		this.value = value;
+	}
+
+	@Override
+	public String getCode() {
+		return code;
+	}
+
+	@Override
+	public String getUnits() {
+		return units;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.ucum.special.SpecialUnitHandler#getValue()
+	 */
+	@Override
+	public BigDecimal value() {		
+		return value;
+	}
+
+	@Override
+	public Unit<Q> unit() {
+		return unit;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitHandler.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitHandler.java
new file mode 100644
index 0000000..a8f1a82
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitHandler.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *    Werner Keil - modularization, integration with other UOMo parts
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.special;
+
+import org.eclipse.uomo.core.ICode;
+import org.unitsofmeasurement.quantity.Quantity;
+
+public abstract class SpecialUnitHandler<Q extends Quantity<Q>> implements Quantity<Q>, ICode {
+
+	/**
+	 * Used to connect this handler with the case sensitive unit
+	 * @return
+	 */
+	public abstract String getCode();
+
+	/** 
+	 * the alternate units to convert to
+	 * TODO use Unit-API here where possible
+	 * @return
+	 */
+	public abstract String getUnits();
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitRegistry.java b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitRegistry.java
new file mode 100644
index 0000000..c4dce43
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/java/org/eclipse/uomo/ucum/special/SpecialUnitRegistry.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2011, Copyright (c) 2006, 2008 Kestral Computing P/L.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing P/L - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.ucum.special;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.uomo.util.Registry;
+import org.unitsofmeasurement.quantity.InformationRate;
+
+@SuppressWarnings("rawtypes")
+public class SpecialUnitRegistry implements Registry<SpecialUnitHandler> {
+	final Map<String, SpecialUnitHandler> handlers = new HashMap<String, SpecialUnitHandler>();
+
+	public SpecialUnitRegistry() {
+		super();
+		init();
+	}
+
+	private void register(SpecialUnitHandler handler) {
+		handlers.put(handler.getCode(), handler);		
+	}
+	
+	private void init() {
+		register(new CelsiusHandler());		
+		register(new FahrenheitHandler());		
+		register(new HoldingHandler("[p'diop]", "deg"));		
+		register(new HoldingHandler("%[slope]", "deg"));		
+		register(new HoldingHandler("[hp_X]", "1"));		
+		register(new HoldingHandler("[hp_C]", "1"));		
+		register(new HoldingHandler("[pH]", "mol/l"));		
+		register(new HoldingHandler("Np", "1"));		
+		register(new HoldingHandler("B", "1"));		
+		register(new HoldingHandler("B[SPL]", "10*-5.Pa", new BigDecimal(2)));		
+		register(new HoldingHandler("B[V]", "V"));		
+		register(new HoldingHandler("B[mV]", "mV"));		
+		register(new HoldingHandler("B[uV]", "uV"));		
+		register(new HoldingHandler("B[W]", "W"));		
+		register(new HoldingHandler("B[kW]", "kW"));		
+		register(new HoldingHandler<InformationRate>("bit_s", "1"));		
+	}
+
+	public boolean exists(String code) {
+		return handlers.containsKey(code);
+	}
+
+	public SpecialUnitHandler get(String code) {
+		return handlers.get(code);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.ucum/src/main/resources/org/eclipse/uomo/ucum/internal/messages.properties b/bundles/org.eclipse.uomo.ucum/src/main/resources/org/eclipse/uomo/ucum/internal/messages.properties
new file mode 100644
index 0000000..2886089
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/src/main/resources/org/eclipse/uomo/ucum/internal/messages.properties
@@ -0,0 +1,15 @@
+DefinitionParser_0=Unable to process XML document
+DefinitionParser_2=Unable to process XML document: expected 'root' but found '
+DefinitionParser_29=Error reading 
+DefinitionParser_3='
+DefinitionParser_30=: 
+DefinitionParser_DateFormat=yyyy-MM-dd' 'HH:mm:ss' 'Z
+DefinitionParser_54=Unexpected content reading 
+DefinitionParser_55=Unexpected state looking for 
+DefinitionParser_56=: at 
+DefinitionParser_57=\  reading 
+DefinitionParser_58=Unexpected element looking for 
+DefinitionParser_59=: found 
+DefinitionParser_60=\  reading 
+DefinitionParser_8=Unexpected text 
+DefinitionParser_9=unknown element name 
diff --git a/bundles/org.eclipse.uomo.ucum/ucum.antlr b/bundles/org.eclipse.uomo.ucum/ucum.antlr
new file mode 100644
index 0000000..c68dd64
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ucum/ucum.antlr
@@ -0,0 +1,23 @@
+ucumExpr   :  DIVIDE expr
+           |  expr 
+           ;
+multiply   :  TIMES term
+           |  DIVIDE term
+           ;
+expr       :  term (multiply)*  
+           ;
+term       :  element (exponent)? (ANN)*
+           ;
+element    :  simpleUnit
+           |  LPAREN expr RPAREN
+           |  ANN
+           ;
+exponent   :  (SIGN)? DIGITS	// allow zero exponent?
+           ;
+simpleUnit :  prefix metricAtom // prefix is token from lexer
+           |  metricAtom  
+           |  nonMetricAtom	// token from lexer
+           |  DIGITS	// allow zero?
+           ;
+metricAtom :  baseUnit // token from lexer
+           |  derivedMetricAtom // token from lexer
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ui/.classpath b/bundles/org.eclipse.uomo.ui/.classpath
new file mode 100644
index 0000000..d6505b8
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/main/resources/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.ui/.gitignore b/bundles/org.eclipse.uomo.ui/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.ui/.project b/bundles/org.eclipse.uomo.ui/.project
new file mode 100644
index 0000000..4d691ae
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bd9078c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.ui
+Bundle-SymbolicName: org.eclipse.uomo.ui
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6,
+ JavaSE-1.7
diff --git a/bundles/org.eclipse.uomo.ui/about.html b/bundles/org.eclipse.uomo.ui/about.html
new file mode 100644
index 0000000..662eb2b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>May 20, 2013</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/bundles/org.eclipse.uomo.ui/about.ini b/bundles/org.eclipse.uomo.ui/about.ini
new file mode 100644
index 0000000..660e6a5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/about.ini
@@ -0,0 +1,17 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%featureText
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=src/main/resources/uomo32.png
+
+# Property "appName" contains name of the application (translated)
+appName=%featureName
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+welcomePage=$nl$/welcome.xml
diff --git a/bundles/org.eclipse.uomo.ui/about.mappings b/bundles/org.eclipse.uomo.ui/about.mappings
new file mode 100644
index 0000000..4511a0a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+0=qualifier
diff --git a/bundles/org.eclipse.uomo.ui/about.properties b/bundles/org.eclipse.uomo.ui/about.properties
new file mode 100644
index 0000000..979850d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/about.properties
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2005, 2013, Werner Keil, Chris Senior, Grahame Grieve and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil - initial API and implementation
+#
+
+# NLS_MESSAGEFORMAT_VAR
+
+featureName=Eclipse UOMo
+
+featureText=Eclipse UOMo Units of Measurement\r\nVersion\: {featureVersion}\r\nBuild id\: {0}\r\n\r\nCopyright (c) 2005, 2013, Werner Keil, Chris Senior, Grahame Grieve and others.  All rights reserved.\r\n\r\nUOMo is a Java/OSGi framework adding Units of Measurement support\r\nto applications based on simple, but type-safe class models.\r\nVisit http\://www.eclipse.org/uomo/
diff --git a/bundles/org.eclipse.uomo.ui/build.properties b/bundles/org.eclipse.uomo.ui/build.properties
new file mode 100644
index 0000000..ba3e5d1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/build.properties
@@ -0,0 +1,8 @@
+bin.includes = about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties,\
+               plugin.properties,\
+               src/main/resources/uomo32.png,\
+               META-INF/
+source.. = src/main/resources/
diff --git a/bundles/org.eclipse.uomo.ui/plugin.properties b/bundles/org.eclipse.uomo.ui/plugin.properties
new file mode 100644
index 0000000..eafaaab
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/plugin.properties
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2005, 2013, Werner Keil, Chris Senior, Grahame Grieve and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil - initial API and implementation
+#
+
+# NLS_MESSAGEFORMAT_VAR
+
+pluginName=Eclipse UOMo
+providerName=Eclipse UOMo
diff --git a/bundles/org.eclipse.uomo.ui/pom.xml b/bundles/org.eclipse.uomo.ui/pom.xml
new file mode 100644
index 0000000..f880b5d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.ui</artifactId>
+	<packaging>eclipse-plugin</packaging>
+	<name>Eclipse UOMo Feature UI</name>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse.png b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse.png
new file mode 100644
index 0000000..7397524
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse.png
Binary files differ
diff --git a/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.gif b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.gif
new file mode 100644
index 0000000..811eccb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.gif
Binary files differ
diff --git a/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.png b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.png
new file mode 100644
index 0000000..568fac1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse32.png
Binary files differ
diff --git a/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse48.png b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse48.png
new file mode 100644
index 0000000..b60ab3c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/src/main/resources/eclipse48.png
Binary files differ
diff --git a/bundles/org.eclipse.uomo.ui/src/main/resources/uomo32.png b/bundles/org.eclipse.uomo.ui/src/main/resources/uomo32.png
new file mode 100644
index 0000000..d2c8715
--- /dev/null
+++ b/bundles/org.eclipse.uomo.ui/src/main/resources/uomo32.png
Binary files differ
diff --git a/bundles/org.eclipse.uomo.units.tests/.classpath b/bundles/org.eclipse.uomo.units.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.units.tests/.gitignore b/bundles/org.eclipse.uomo.units.tests/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.units.tests/.project b/bundles/org.eclipse.uomo.units.tests/.project
new file mode 100644
index 0000000..1453401
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.units.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.units.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.units.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..798183c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.units.tests
+Bundle-SymbolicName: org.eclipse.uomo.units.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.units;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.uomo.units,
+ org.eclipse.uomo.units.impl,
+ org.eclipse.uomo.units.impl.format,
+ org.eclipse.uomo.units.impl.quantity
+Require-Bundle: org.junit;bundle-version="4.8.2"
diff --git a/bundles/org.eclipse.uomo.units.tests/build.properties b/bundles/org.eclipse.uomo.units.tests/build.properties
new file mode 100644
index 0000000..ced5f40
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.units.tests/pom.xml b/bundles/org.eclipse.uomo.units.tests/pom.xml
new file mode 100644
index 0000000..6f2cdf5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.units.tests</artifactId>
+	<name>UOMo Units of Measurement Tests</name>
+	<packaging>eclipse-test-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/QuantityAmountTest.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/QuantityAmountTest.java
new file mode 100644
index 0000000..210967d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/QuantityAmountTest.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Martin Desruisseaux, Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.Prefix.CENTI;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.junit.Test;
+
+/**
+ * Tests {@link QuantityAmount} implementations and subclasses.
+ * 
+ * @author Martin Desruisseaux
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version $Revision$, $Date$
+ */
+public class QuantityAmountTest {
+
+    /**
+     * Tests the creation quantities backed by the {@code double} primitive
+     * type.
+     */
+    @Test
+    public void testDouble() {
+	// final QuantityFactory<Length> factory =
+	// QuantityFactory.getInstance(Length.class);
+	final LengthAmount length = new LengthAmount(Double.valueOf(4.0), METRE);
+
+	assertSame("Wrong tuple element.", METRE, length.unit());
+	assertEquals("Wrong tuple element.", Double.valueOf(4.0), 
+			length.value());
+	assertEquals("Wrong conversion.", 4.0, length.doubleValue(METRE), 0.0);
+	assertEquals("Wrong conversion.", 0.04, length
+		.doubleValue(CENTI(METRE)), 0.0);
+
+	final LengthAmount other = new LengthAmount(8.0, METRE);
+	assertSame("Expected same implementation class.", length.getClass(),
+		other.getClass());
+	assertFalse("Quantities shall not be equal.", length.equals(other));
+	assertFalse("Quantities shall not be equal.",
+		length.hashCode() == other.hashCode());
+
+	final LengthAmount equivalent = new LengthAmount(Double.valueOf(4.0),
+		METRE);
+	assertSame("Expected same implementation class.", length.getClass(),
+		equivalent.getClass());
+	assertFalse("Quantities shall not be equal.", equivalent.equals(other));
+	assertEquals("Quantities shall be equal.", equivalent, length); // .equals(length));
+	assertTrue("'equals' shall be symmetric.", length.equals(equivalent));
+	assertEquals("Expected same hash code.", length.hashCode(), equivalent
+		.hashCode());
+    }
+
+    /**
+     * Tests the creation quantities backed by the {@link Number} class.
+     */
+    @Test
+    public void testNumber() {
+	// final QuantityFactory<Length> factory =
+	// QuantityFactory.getInstance(Length.class);
+	final BigInteger value = BigInteger.valueOf(4);
+	final LengthAmount length = new LengthAmount(value, METRE);
+
+	assertSame("Wrong tuple element.", METRE, length.unit());
+	assertEquals("Wrong tuple element.", BigInteger.valueOf(4), length.value());
+	assertEquals("Wrong conversion.", 4.0, length.doubleValue(METRE), 0.0);
+	assertEquals("Wrong conversion.", 0.04, length
+		.doubleValue(CENTI(METRE)), 0.0);
+
+	// Quantity equivalent to 'length', but backed by a double.
+	// This is not the same class, but should nevertheless by considered
+	// equivalent.
+	final LengthAmount equivalent = new LengthAmount(4, METRE);
+	assertTrue("Quantities shall be equal.", equivalent.equals(length));
+	assertTrue("'equals' shall be symmetric.", length.equals(equivalent));
+	assertEquals("Expected same hash code.", length.hashCode(), equivalent
+		.hashCode());
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/SITest.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/SITest.java
new file mode 100644
index 0000000..e5582b7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/SITest.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.print;
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+import static org.eclipse.uomo.units.SI.GRAM;
+import static org.eclipse.uomo.units.SI.KILOGRAM;
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.Prefix.MILLI;
+import static org.eclipse.uomo.units.impl.system.USCustomary.LITER;
+import static org.eclipse.uomo.units.impl.system.USCustomary.METER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.quantity.Volume;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Unit test for class org.eclipse.uomo.units.SI
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3 ($Revision: 172 $), $Date: 2010-02-21 20:02:14 +0100 (So, 21
+ *          Feb 2010) $
+ */
+public class SITest {
+	SystemOfUnits result;
+
+	@Before
+	public void setUp() throws Exception {
+		result = SI.getInstance();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		result = null;
+	}
+
+	//
+	// public static void main(String[] args) {
+	// new SITest("").testGetInstance();
+	// }
+	/**
+	 * Test of getInstance method, of class SI.
+	 */
+	@Test
+	public void testGetInstance() {
+		// print("getInstance: " + NonSI.GALLON_UK.divide(8) + " (" +
+		// NonSI.GALLON_UK.divide(8).getDimension().toString() + ")");
+
+		// Checks SI contains the 7 SI base units.
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("m")));
+		assertTrue(result.getUnits().contains(SI.KILOGRAM)); // TODO check
+																// parsing: "kg"
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("s")));
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("mol")));
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("K")));
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("cd")));
+		assertTrue(result.getUnits().contains(AbstractUnit.valueOf("A")));
+
+		print(AbstractUnit.valueOf("m"));
+		println(AbstractUnit.valueOf("m").getDimension().toString());
+	}
+
+	@Test
+	public void testMass() {
+		assertTrue(GRAM.isCompatible(KILOGRAM));
+		Unit<Mass> MILLIGRAM = MILLI(GRAM);
+		println(MILLIGRAM);
+	}
+
+	@Test
+	public void testVolume() {
+		// print("ML: ");
+		Unit<Volume> MILLILITER = MILLI(LITER);
+		println(MILLILITER);
+	}
+
+	@Test
+	public void testSIvsUS() {
+		assertEquals(METRE, METER);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/UnitTest.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/UnitTest.java
new file mode 100644
index 0000000..ad2329c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/UnitTest.java
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+import static org.eclipse.uomo.units.SI.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.unitsofmeasurement.quantity.Dimensionless;
+import org.unitsofmeasurement.quantity.Power;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+
+/**
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version $Revision: 195 $, $LastChangedDate: 2010-02-24 18:40:34 +0100 (Mi, 24 Feb 2010) $
+ */
+public class UnitTest {
+	Unit<Dimensionless> one;
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    @Before
+    public void setUp() throws Exception {
+//      super.setUp();
+        one = AbstractUnit.ONE;
+    }
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    @After
+    public void tearDown() throws Exception {
+//      super.tearDown();
+        one = null;
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#toMetric()}.
+     */
+//    @Test
+//    public void testToMetric() {
+//        AbstractUnit<? extends QuantityAmount> su = (AbstractUnit<? extends QuantityAmount>) one.toMetric();
+//        assertTrue(su.isUnscaledMetric());
+//    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#getConverterTo}.
+     */
+    @Test
+    public void testConverterToSI() {
+        Double factor = new Double(10);
+        UnitConverter converter = one.getConverterTo(one);
+        Double result = converter.convert(factor.doubleValue());
+        assertEquals(result, factor);
+        println(result.toString());
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#isMetric()}.
+     */
+//    @Test
+//    public void testIsMetric() {
+//        boolean standard = one.isMetric();
+//        assertTrue(standard);
+//    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#asType(java.lang.Class)}.
+     */
+  @Test
+  @Ignore
+  public void testAsType() {
+      one.asType(Dimensionless.class);
+      try {
+          METRE.asType(Dimensionless.class);
+          fail("Should have raised ClassCastException");
+      } catch (ClassCastException e) {
+          assertTrue(true);
+      }
+  }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#getDimension()}.
+     */
+    @Test
+    public void testGetDimension() {
+        one.getDimension();
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#alternate(java.lang.String)}.
+     */
+    @Test
+    public void testAlternate() {
+        Unit<?> alternate = one.alternate(null);
+        assertNotNull(alternate);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#compound(org.unitsofmeasure.Unit)}.
+     */
+    /*public void testCompound() {
+        Unit<? extends Quantity> compound = one.compound(one);
+        assertNotNull(compound);
+    }*/
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#transform}.
+     */
+    @Test
+    public void testTransform() {
+        Unit<?> result = one.transform(AbstractConverter.IDENTITY);
+        assertEquals(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#add(double)}.
+     */
+    @Test
+    public void testAdd() {
+    	Unit<?> result = one.add(10);
+        assertNotSame(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#multiply(long)}.
+     */
+    @Test
+    public void testMultiplyLong() {
+    	Unit<?> result = one.multiply(2L);
+        assertNotSame(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#multiply(double)}.
+     */
+    @Test
+    public void testMultiplyDouble() {
+    	Unit<?> result = one.multiply(2.1);
+        assertNotSame(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#multiply(org.unitsofmeasure.Unit)}.
+     */
+    @Test
+    public void testMultiplyUnitOfQ() {
+        AbstractUnit<?> result = (AbstractUnit<?>) one.multiply(one);
+        assertEquals(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#inverse()}.
+     */
+    @Test
+    public void testInverse() {
+    	Unit<?> result = one.inverse();
+        assertEquals(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#divide(long)}.
+     */
+    @Test
+    public void testDivideLong() {
+    	Unit<?> result = one.divide(2L);
+        assertNotSame(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#divide(double)}.
+     */
+    @Test
+    public void testDivideDouble() {
+    	Unit<?> result = one.divide(3.2);
+        assertNotSame(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#divide(org.unitsofmeasure.Unit)}.
+     */
+    @Test
+    public void testDivideUnitOfQ() {
+    	Unit<?> result = one.divide(one);
+        assertEquals(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#root(int)}.
+     */
+    @Test
+    public void testRoot() {
+    	Unit<?> result = one.root(2);
+        assertEquals(result, one);
+    }
+
+    /**
+     * Test method for {@link org.unitsofmeasure.Unit#pow(int)}.
+     */
+    @Test
+    public void testPow() {
+    	Unit<?> result = one.pow(10);
+        assertEquals(result, one);
+    }
+    
+    @Test
+    public void testKiloIsAThousand() {
+    	//FIXME: Need to find the org.hamcrest assertion libs
+    	BaseAmount<Power> w2000 = new BaseAmount<Power>(2000, WATT);
+    	BaseAmount<Power> kW2 = new BaseAmount<Power>(2, Prefix.KILO(WATT));
+    	//assertThat(w2000, is(kW2));
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/Benchmark.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/Benchmark.java
new file mode 100644
index 0000000..b26c4b1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/Benchmark.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import static org.eclipse.uomo.units.SI.GRAM;
+import static org.eclipse.uomo.units.SI.KILOGRAM;
+import static org.eclipse.uomo.units.SI.Prefix.*;
+
+import java.util.Random;
+import java.util.logging.Logger;
+
+import org.eclipse.uomo.units.impl.quantity.MassAmount;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version $Revision$, $Date$
+ * @param <Q> a quantity
+ */
+public class Benchmark<Q extends Quantity<Q>> {
+    // Create logger object (usually with the class name)
+	private static Logger benchmarkLogger = Logger.getLogger(Benchmark.class.getName());
+	
+	private static final int N = 100000;
+
+	// Because of generic array creation.
+	private static final Unit<?>[] UNITS = new Unit[] { MEGA(GRAM), KILOGRAM,
+			GRAM, CENTI(GRAM), MILLI(GRAM), MICRO(GRAM) };
+
+	@SuppressWarnings("unchecked")
+	private static long usingQuantities(final long seed) {
+		long time = System.currentTimeMillis();
+		final Random r = new Random(seed);
+		// final QuantityFactory<Mass> factory =
+		// QuantityFactory.getInstance(Mass.class);
+		final MassAmount[] m = new MassAmount[N];
+		for (int i = 0; i < N; i++) {
+			m[i] = new MassAmount(r.nextGaussian(), KILOGRAM);
+		}
+		// Now perform some computation in a random unit.
+		@SuppressWarnings("rawtypes")
+		final Unit targetUnit = (Unit<?>) UNITS[r.nextInt(UNITS.length)];
+		double sum = 0;
+		for (int i = 0; i < N; i++) {
+			sum += m[i].doubleValue(targetUnit);
+		}
+		time = System.currentTimeMillis() - time;
+		benchmarkLogger.info("Using quantities: ellapsed time=" + (time / 1000f)
+				+ " s., result=" + sum);
+		return time;
+	}
+
+	private static long usingDouble(final long seed)
+			throws UnconvertibleException, IncommensurableException {
+		long time = System.currentTimeMillis();
+		final Random r = new Random(seed);
+		final double[] m = new double[N];
+		for (int i = 0; i < N; i++) {
+			m[i] = r.nextGaussian();
+		}
+		// Now perform some computation in a random unit.
+		final Unit<?> sourceUnit = KILOGRAM;
+		final Unit<?> targetUnit = (Unit<?>) UNITS[r.nextInt(UNITS.length)];
+		UnitConverter cv = sourceUnit.getConverterToAny((Unit<?>) targetUnit);
+		double sum = 0;
+		for (int i = 0; i < N; i++) {
+			sum += cv.convert(m[i]);
+		}
+		time = System.currentTimeMillis() - time;
+		benchmarkLogger.info("Using primitives: ellapsed time=" + (time / 1000f)
+				+ " s., result=" + sum);
+		return time;
+	}
+
+	public static void main(String[] args) throws InterruptedException {
+		// TODO add IE and UE to main
+		// Execute the loop many time for letting Hotspot to "warn up".
+		try {
+			final Random r = new Random();
+			for (int i = 0; i < 20; i++) {
+				final long seed = r.nextLong();
+				long t1 = usingQuantities(seed);
+				long t2 = usingDouble(seed);
+				benchmarkLogger.fine("Ratio: " + (float) t1 / (float) t2);
+				Thread.sleep(100);
+			}
+		} catch (IncommensurableException ie) {
+			throw new InterruptedException();
+		} catch (UnconvertibleException ue) {
+			throw new InterruptedException();
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/format/UnitFormatTest.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/format/UnitFormatTest.java
new file mode 100644
index 0000000..92ccc23
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/format/UnitFormatTest.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.format;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.*;
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.Prefix.CENTI;
+import static org.eclipse.uomo.units.SI.Prefix.KILO;
+import static org.eclipse.uomo.units.SI.Prefix.MILLI;
+import static org.eclipse.uomo.units.impl.system.USCustomary.ELECTRON_VOLT;
+import static org.eclipse.uomo.units.impl.system.USCustomary.FOOT;
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+import org.eclipse.uomo.units.AbstractUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version $Revision: 206 $, $Date: 2010-02-25 02:40:17 +0100 (Do, 25 Feb 2010)
+ *          $
+ */
+public class UnitFormatTest {
+	private static final String COMPARISON_FOOT = "ft";
+	private static final String COMPARISON_KM = "km";
+	private static final Locale COMPARISON_LOCALE = Locale.UK;
+	private static final Locale MULTI_LOCALE = Locale.ENGLISH;
+
+	LocalUnitFormatImpl format;
+	Unit<Length> cm;
+	Unit<Length> mm;
+	Unit<Length> foot;
+
+	@Before
+	public void setUp() throws Exception {
+		// setName(UCUMFormatTest.class.getSimpleName());
+		cm = CENTI(METRE);
+		mm = MILLI(METRE);
+		foot = FOOT;
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		// super.tearDown();
+	}
+
+	@Test
+	public void testDefault() {
+		format = LocalUnitFormatImpl.getInstance();
+		// format.format(unit, appendable);
+		String formattedText = format.format(cm);
+		println(formattedText);
+		// System.out.println(unit2);
+		formattedText = format.format(mm);
+		println(formattedText);
+		formattedText = format.format(foot);
+		print(formattedText);
+	}
+
+	@Test
+	public void testGetInstanceLocale() {
+		format = LocalUnitFormatImpl.getInstance(COMPARISON_LOCALE);
+		String formattedText = format.format(cm);
+		print(formattedText);
+		// System.out.println(unit2);
+		formattedText = format.format(mm);
+		print(formattedText);
+		formattedText = format.format(foot);
+		print(formattedText);
+		assertEquals(COMPARISON_FOOT, formattedText);
+	}
+
+	@Test
+	public void testUSVolt() {
+		print(ELECTRON_VOLT.getDimension().toString());
+		println(ELECTRON_VOLT.toString());
+	}
+
+	@Test
+	public void testSubMultiples() {
+		Unit<Length> u = CENTI(METRE);
+		println(u.toString());
+	}
+
+	/**
+	 * Tests the {@link AbstractUnit#toString()} method, which is backed by
+	 * {@link BaseFormat}.
+	 * 
+	 * @see http://kenai.com/jira/browse/JSR_275-43
+	 */
+	@Test
+	public void testMultiples() {
+		format = LocalUnitFormatImpl.getInstance(MULTI_LOCALE);
+		assertEquals("m", format.format(METRE));
+		// Multiples
+		assertEquals(COMPARISON_KM, format.format(KILO(METRE)));
+		assertEquals(COMPARISON_KM, format.format(METRE.multiply(1000)));
+		assertEquals(COMPARISON_KM, format.format(METRE.multiply(1000d)));
+		assertEquals("Tm", METRE.multiply(BigInteger.TEN.pow(12).longValue())
+				.toString());
+		// Submultiples
+		assertEquals("cm", format.format(METRE.divide(100d)));
+		assertEquals("mm", format.format(METRE.divide(1000d)));
+		assertEquals("fm", format.format(METRE.divide(BigInteger.TEN.pow(15).
+				longValue())));
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/quantity/QuantityTest.java b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/quantity/QuantityTest.java
new file mode 100644
index 0000000..a9d50aa
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units.tests/src/org/eclipse/uomo/units/impl/quantity/QuantityTest.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.*;
+import static org.eclipse.uomo.units.SI.AMPERE_TURN;
+import static org.eclipse.uomo.units.SI.KILOGRAM;
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.METRES_PER_SQUARE_SECOND;
+import static org.eclipse.uomo.units.SI.Prefix.KILO;
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.uomo.units.impl.quantity.AccelerationAmount;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.eclipse.uomo.units.impl.quantity.MagnetomotiveForceAmount;
+import org.eclipse.uomo.units.impl.quantity.MassAmount;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version $Revision$, $Date$
+ */
+public class QuantityTest {
+	LengthAmount length;
+	AccelerationAmount accel;
+	MagnetomotiveForceAmount magneto;
+	
+    // universal gravitational constant  (m3 kg-1 s-2)
+    private static final double G = 6.67300E-11;
+	
+	private MassAmount mass;   // in kilograms
+	private LengthAmount radius; // in meters
+
+	
+	@Before
+	public void setUp() throws Exception {
+		length  = new LengthAmount(4.0, METRE);
+		accel   = new AccelerationAmount(30, METRES_PER_SQUARE_SECOND);
+		magneto = new MagnetomotiveForceAmount(50, AMPERE_TURN);
+		
+		mass 	= new MassAmount(30, KILOGRAM);
+		radius  = new LengthAmount(400, KILO(METRE));
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		length = null;
+	}
+
+	@Test
+	public void testLength() {
+		LengthAmount len2 = new LengthAmount(4.0, METRE);
+		assertEquals(length, len2);
+	}
+	
+	private AccelerationAmount surfaceGravity() {
+        double m = mass.doubleValue(KILOGRAM);
+        double r = radius.doubleValue(METRE);
+        return new AccelerationAmount(
+                G * m / (r * r), METRES_PER_SQUARE_SECOND);
+    }
+	
+	@Test
+	public void testAccelo1() {
+		AccelerationAmount ac1 = surfaceGravity();
+		print("Gravity: ");
+		println(ac1);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/.classpath b/bundles/org.eclipse.uomo.units/.classpath
new file mode 100644
index 0000000..a227bcc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry exported="true" kind="lib" path="libs/icu4j-50_1_1.jar"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="src" path="src/main/resources/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.units/.gitignore b/bundles/org.eclipse.uomo.units/.gitignore
new file mode 100644
index 0000000..2c36b17
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/.gitignore
@@ -0,0 +1,2 @@
+/target
+/.settings
diff --git a/bundles/org.eclipse.uomo.units/.project b/bundles/org.eclipse.uomo.units/.project
new file mode 100644
index 0000000..3427e35
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/.project
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.units</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.jboss.tools.jst.web.kb.kbbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.jboss.tools.jst.web.kb.kbnature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.units/.springBeans b/bundles/org.eclipse.uomo.units/.springBeans
new file mode 100644
index 0000000..6c6cb5a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.5.0.201010221000-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.units/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.units/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..034321e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/META-INF/MANIFEST.MF
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.units
+Bundle-SymbolicName: org.eclipse.uomo.units;singleton:=true
+Bundle-Version: 0.6.0.qualifier
+Bundle-Activator: org.eclipse.uomo.units.Activator
+Bundle-Vendor: Eclipse OSBP
+Import-Package: org.eclipse.osgi.util;version="1.1.0",
+ org.osgi.framework;version="1.3.0",
+ org.osgi.util.tracker;version="1.3.1"
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.uomo.units,
+ org.eclipse.uomo.units.impl;
+  uses:="org.unitsofmeasurement.unit,
+   org.eclipse.uomo.units",
+ org.eclipse.uomo.units.impl.converter;
+  uses:="org.unitsofmeasurement.unit,
+   org.eclipse.uomo.units",
+ org.eclipse.uomo.units.impl.format,
+ org.eclipse.uomo.units.impl.quantity;
+  uses:="org.eclipse.uomo.units.impl,
+   org.unitsofmeasurement.quantity,
+   org.unitsofmeasurement.unit,
+   org.eclipse.uomo.units",
+ org.eclipse.uomo.units.impl.system;
+  uses:="org.unitsofmeasurement.unit,
+   org.eclipse.uomo.units,
+   org.unitsofmeasurement.service"
+Require-Bundle: org.eclipse.uomo.core;bundle-version="0.6.0",
+ org.unitsofmeasurement.unit-api;bundle-version="0.6.1"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ClassPath: libs/icu4j-50_1_1.jar,.
diff --git a/bundles/org.eclipse.uomo.units/build.properties b/bundles/org.eclipse.uomo.units/build.properties
new file mode 100644
index 0000000..1f1733f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/build.properties
@@ -0,0 +1,6 @@
+source.. = src/main/java/,\
+           src/main/resources/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               libs/icu4j-50_1_1.jar
diff --git a/bundles/org.eclipse.uomo.units/libs/icu4j-50_1_1.jar b/bundles/org.eclipse.uomo.units/libs/icu4j-50_1_1.jar
new file mode 100644
index 0000000..4994a5c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/libs/icu4j-50_1_1.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.units/plugin.xml b/bundles/org.eclipse.uomo.units/plugin.xml
new file mode 100644
index 0000000..5535690
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/plugin.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+</plugin>
diff --git a/bundles/org.eclipse.uomo.units/pom.xml b/bundles/org.eclipse.uomo.units/pom.xml
new file mode 100644
index 0000000..5e41157
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/pom.xml
@@ -0,0 +1,25 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.units</artifactId>
+	<name>UOMo Units of Measurement</name>
+	<packaging>eclipse-plugin</packaging>
+
+	<properties>
+		<site.basedir>${project.parent.basedir}</site.basedir>
+	</properties>
+
+<!-- 	<dependencies> -->
+<!-- 		<dependency> -->
+<!-- 			<groupId>com.ibm.icu</groupId> -->
+<!-- 			<artifactId>icu4j</artifactId> -->
+<!-- 			<version>50.1.1</version> -->
+<!-- 		</dependency> -->
+<!-- 	</dependencies> -->
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units/src/etc/header.txt b/bundles/org.eclipse.uomo.units/src/etc/header.txt
new file mode 100644
index 0000000..5fb4853
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/etc/header.txt
@@ -0,0 +1,8 @@
+Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+
+Contributors:
+    Werner Keil - initial API and implementation
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/.gitignore b/bundles/org.eclipse.uomo.units/src/main/java/.gitignore
new file mode 100644
index 0000000..1a70481
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/.gitignore
@@ -0,0 +1 @@
+/META-INF
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractConverter.java
new file mode 100644
index 0000000..5d7a880
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractConverter.java
@@ -0,0 +1,276 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.Arrays;
+import java.util.List;
+
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This class represents a converter of numeric values.</p>
+ *
+ * <p> It is not required for sub-classes to be immutable
+ *     (e.g. currency converter).</p>
+ *
+ * <p> Sub-classes must ensure unicity of the {@linkplain #IDENTITY identity}
+ *     converter. In other words, if the result of an operation is equivalent
+ *     to the identity converter, then the unique {@link #IDENTITY} instance
+ *     should be returned.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4 ($Revision: 231 $), $Date: 2010-10-13 16:53:37 +0200 (Mi, 13 Okt 2010) $
+ */
+public abstract class AbstractConverter implements UnitConverter, Serializable {
+
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 2557410026012911803L;
+
+    /**
+     * Holds the identity converter (unique). This converter does nothing
+     * (<code>ONE.convert(x) == x</code>). This instance is unique.
+     */
+    public static final UnitConverter IDENTITY = new Identity();
+
+    /**
+     * Default constructor.
+     */
+    protected AbstractConverter() {
+    }
+
+    /**
+     * Returns the inverse of this converter. If <code>x</code> is a valid
+     * value, then <code>x == inverse().convert(convert(x))</code> to within
+     * the accuracy of computer arithmetic.
+     *
+     * @return the inverse of this converter.
+     */
+    public abstract UnitConverter inverse();
+
+    /**
+     * Indicates whether this converter is considered to be the the same as the
+     * one specified.
+     *
+     * @param  cvtr the converter with which to compare.
+     * @return <code>true</code> if the specified object is a converter
+     *         considered equals to this converter;<code>false</code> otherwise.
+     */
+//    @Override
+//    public abstract boolean equals(Object cvtr);
+
+    /**
+     * Returns a hash code value for this converter. Equals object have equal
+     * hash codes.
+     *
+     * @return this converter hash code value.
+     * @see    #equals
+     */
+    //@Override
+    //public abstract int hashCode();
+
+    /**
+     * Concatenates this converter with another converter. The resulting
+     * converter is equivalent to first converting by the specified converter
+     * (right converter), and then converting by this converter (left converter).
+     *
+     * <p>Note: Implementations must ensure that the {@link #IDENTITY} instance
+     *          is returned if the resulting converter is an identity
+     *          converter.</p>
+     *
+     * @param  converter the other converter.
+     * @return the concatenation of this converter with the other converter.
+     */
+    public UnitConverter concatenate(UnitConverter converter) {
+        return (converter == IDENTITY) ? this : new CompoundImpl(this, converter);
+    }
+	
+    @Override
+	public boolean isIdentity() {
+		return false;
+	}
+
+	@Override
+	public List<UnitConverter> getCompoundConverters() {
+		return Arrays.asList((UnitConverter)new CompoundImpl(this, this));
+	}
+	
+    /**
+     * This interface is implemented by converters made up of two
+     * separate converters (in matrix notation
+     * <code>[compound] = [left] x [right]</code>).
+     */
+    public interface Compound {
+
+        /**
+         * Returns the left converter of this compound converter
+         * (the last one performing the conversion).
+         *
+         * @return the left converter.
+         */
+        AbstractConverter getLeft();
+
+        /**
+         * Returns the right converter of this compound converter
+         * (the first one performing the conversion).
+         *
+         * @return the right converter.
+         */
+        AbstractConverter getRight();
+    }
+
+    /**
+     * This inner class represents the identity converter (singleton).
+     */
+    private static final class Identity extends AbstractConverter {
+
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 7675901502919547460L;
+
+        @Override
+        public Identity inverse() {
+            return this;
+        }
+
+        @Override
+        public double convert(double value) {
+            return value;
+        }
+
+        @Override
+        public BigDecimal convert(BigDecimal value, MathContext ctx) {
+            return value;
+        }
+
+		public Number convert(Number value) {
+			return value;
+		}
+		
+        @Override
+        public boolean equals(Object cvtr) {
+            return this == cvtr; // Unique instance.
+        }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        @Override
+        public boolean isLinear() {
+            return true;
+        }
+
+		@Override
+		public boolean isIdentity() {
+			return true;
+		}
+    }
+
+    /**
+     * This inner class represents a compound converter (non-linear).
+     */
+    private static final class CompoundImpl extends AbstractConverter implements Compound {
+
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 2242882007946934958L;
+
+        /**
+         * Holds the first converter.
+         */
+        private final AbstractConverter left;
+
+        /**
+         * Holds the second converter.
+         */
+        private final AbstractConverter right;
+
+        /**
+         * Creates a compound converter resulting from the combined
+         * transformation of the specified converters.
+         *
+         * @param  unitConverter the left converter.
+         * @param  unitConverter2 the right converter.
+         */
+        private CompoundImpl(UnitConverter unitConverter, UnitConverter unitConverter2) {
+            this.left = (AbstractConverter) unitConverter;
+            this.right = (AbstractConverter) unitConverter2;
+        }
+
+        @Override
+        public UnitConverter inverse() {
+            return new CompoundImpl(right.inverse(), left.inverse());
+        }
+
+        @Override
+        public double convert(double value) {
+            return left.convert(right.convert(value));
+        }
+
+        @Override
+        public BigDecimal convert(BigDecimal value, MathContext ctx) {
+            return left.convert(right.convert(value, ctx), ctx);
+        }
+
+
+		public Number convert(Number value) {
+			return left.convert(right.convert(value));
+		}
+        
+        @Override
+        public boolean equals(Object cvtr) {
+            if (this == cvtr)
+                return true;
+            if (!(cvtr instanceof Compound))
+                return false;
+            Compound that = (Compound) cvtr;
+            return (this.left.equals(that.getLeft()))
+                    && (this.right.equals(that.getRight()));
+        }
+
+        @Override
+        public int hashCode() {
+            return left.hashCode() + right.hashCode();
+        }
+
+        @Override
+        public boolean isLinear() {
+            return left.isLinear() && right.isLinear();
+        }
+
+        public AbstractConverter getLeft() {
+            return left;
+        }
+
+        public AbstractConverter getRight() {
+            return right;
+        }
+
+		@Override
+		public UnitConverter concatenate(UnitConverter converter) {
+			return (converter == IDENTITY) ? this : new CompoundImpl(this, converter);
+		}
+
+		@Override
+		public List<UnitConverter> getCompoundConverters() {
+			return Arrays.asList((UnitConverter)new CompoundImpl(this, this));
+		}
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractFormat.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractFormat.java
new file mode 100644
index 0000000..f4613b2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractFormat.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.io.IOException;
+import java.text.ParsePosition;
+
+import org.eclipse.uomo.units.impl.format.LocalUnitFormatImpl;
+import org.eclipse.uomo.units.impl.system.USCustomary;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitFormat;
+
+import com.ibm.icu.text.UFormat;
+import com.ibm.icu.util.ULocale;
+
+
+/**
+ * <p> This class provides the interface for formatting and parsing {@link
+ *     AbstractUnit units}.</p>
+ *
+ * <p> For all metric units, the 20 SI prefixes used to form decimal
+ *     multiples and sub-multiples of SI units are recognized.
+ *     {@link USCustomary US Customary} units are directly recognized. For example:[code]
+ *        Unit.valueOf("m°C").equals(SI.MILLI(SI.CELSIUS))
+ *        Unit.valueOf("kW").equals(SI.KILO(SI.WATT))
+ *        Unit.valueOf("ft").equals(SI.METRE.multiply(3048).divide(10000))[/code]</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.5.1 ($Revision: 215 $), $Date: 2010-09-19 22:12:08 +0200 (So, 19 Sep 2010) $
+ * 
+ */
+public abstract class AbstractFormat extends UFormat implements UnitFormat {
+
+   /**
+     * Returns the {@link SymbolMap} for this unit format.
+     *
+     * @return the symbol map used by this format.
+     */
+    protected abstract SymbolMap getSymbolMap();
+
+    /**
+     * Formats the specified unit.
+     *
+     * @param unit the unit to format.
+     * @param appendable the appendable destination.
+     * @return The appendable destination passed in as {@code appendable},
+     *         with formatted text appended.
+     * @throws IOException if an error occurs.
+     */
+    public abstract Appendable format(Unit<?> unit, Appendable appendable)
+            throws IOException;
+
+    /**
+     * Parses a portion of the specified <code>CharSequence</code> from the
+     * specified position to produce a unit. If there is no unit to parse
+     * {@link AbstractUnit#ONE} is returned.
+     *
+     * @param csq the <code>CharSequence</code> to parse.
+     * @param cursor the cursor holding the current parsing index.
+     * @return the unit parsed from the specified character sub-sequence.
+     * @throws IllegalArgumentException if any problem occurs while parsing the
+     *         specified character sequence (e.g. illegal syntax).
+     */
+    public abstract Unit<?> parse(CharSequence csq, ParsePosition cursor)
+            throws IllegalArgumentException;
+
+    /**
+     * Return a formatter for CurrencyAmount objects in the given
+     * locale.
+     * @param locale desired locale
+     * @return a formatter object
+     * @stable ICU 3.0
+     */
+    public static AbstractFormat getUnitFormat(ULocale locale) {
+        return LocalUnitFormatImpl.getInstance(locale.toLocale());
+    }
+
+    /**
+     * Return a formatter for CurrencyAmount objects in the default
+     * locale.
+     * @return a formatter object
+     * @stable ICU 3.0
+     */
+    public static AbstractFormat getUnitFormat() {
+        return getUnitFormat(ULocale.getDefault());
+    }
+    
+    /**
+     * Convenience method equivalent to {@link #format(AbstractUnit, Appendable)}
+     * except it does not raise an IOException.
+     *
+     * @param unit the unit to format.
+     * @param dest the appendable destination.
+     * @return the specified <code>StringBuilder</code>.
+     */
+    final StringBuilder format(AbstractUnit<?> unit, StringBuilder dest) {
+        try {
+            return (StringBuilder) this.format(unit, (Appendable) dest);
+        } catch (IOException ex) {
+            throw new Error(ex); // Can never happen.
+        }
+    }
+
+    /**
+     * serialVersionUID
+     */
+    private static final long serialVersionUID = -2046025267890654321L;
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractSystemOfUnits.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractSystemOfUnits.java
new file mode 100644
index 0000000..aa48a76
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractSystemOfUnits.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.uomo.core.IName;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p> An abstract base class for unit systems.</p>
+ *
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2011-09-11 14:52:11 +0200 (So, 11 Sep 2011) $
+ */
+public abstract class AbstractSystemOfUnits implements SystemOfUnits, IName {
+	/**
+	 * Holds collection of units.
+	 */
+	protected static final Set<Unit<?>> UNITS = new HashSet<Unit<?>>();
+
+	// ///////////////////
+	// Collection View //
+	// ///////////////////
+	/**
+	 * Returns a read only view over the units defined in this class.
+	 * 
+	 * @return the collection of units.
+	 */
+	public Set<Unit<?>> getUnits() {
+		return Collections.unmodifiableSet(UNITS);
+	}
+	
+	@Override
+	public Set<Unit<?>> getUnits(Dimension dimension) {
+		return Helper.getUnitsOfDimension(UNITS, dimension);
+	}
+
+	@Override
+	public <Q extends Quantity<Q>> Unit<Q> getUnit(Class<Q> quantityType) {
+		return QuantityFactory.getInstance(quantityType).getMetricUnit();
+	}
+	
+	/**
+	 * Adds a new named unit to the collection.
+	 * 
+	 * @param unit the unit being added.
+	 * @param name the name of the unit.
+	 * @return <code>unit</code>.
+	 */
+	@SuppressWarnings("unchecked")
+	protected static <U extends Unit<?>> U addUnit(U unit, String name) {
+		if (name != null && unit instanceof AbstractUnit) {
+			AbstractUnit<?> aUnit = (AbstractUnit<?>)unit;
+			aUnit.setName(name);
+			UNITS.add(aUnit);
+			return (U) aUnit;
+		}
+		UNITS.add(unit);
+		return unit;
+	}
+
+	/**
+	 * Adds a new unit to the collection.
+	 * 
+	 * @param unit
+	 *            the unit being added.
+	 * @return <code>unit</code>.
+	 */
+	protected static <U extends Unit<?>> U addUnit(U unit) {
+		UNITS.add(unit);
+		return unit;
+	}
+	static class Helper {
+		static Set<Unit<?>> getUnitsOfDimension(final Set<Unit<?>> units, 
+				Dimension dimension) {
+			if (dimension != null) {
+				Set<Unit<?>>dimSet = new HashSet<Unit<?>>();
+				for (Unit<?> u : units) {
+					if (dimension.equals(u.getDimension())) {
+						dimSet.add(u);
+					}
+				}
+				return dimSet;
+			}
+			return null;
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractUnit.java
new file mode 100644
index 0000000..cadb0b6
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/AbstractUnit.java
@@ -0,0 +1,654 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle, Steve Emmerson  
+ *    - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.text.ParsePosition;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.uomo.core.IName;
+import org.eclipse.uomo.core.ISymbol;
+import org.eclipse.uomo.units.impl.AlternateUnit;
+import org.eclipse.uomo.units.impl.BaseUnit;
+import org.eclipse.uomo.units.impl.DimensionImpl;
+import org.eclipse.uomo.units.impl.ProductUnit;
+import org.eclipse.uomo.units.impl.TransformedUnit;
+import org.eclipse.uomo.units.impl.converter.AddConverter;
+import org.eclipse.uomo.units.impl.converter.LogConverter;
+import org.eclipse.uomo.units.impl.converter.MultiplyConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.eclipse.uomo.units.impl.format.LocalUnitFormatImpl;
+import org.unitsofmeasurement.quantity.Dimensionless;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+import org.unitsofmeasurement.unit.UnitFormat;
+
+import com.ibm.icu.util.MeasureUnit;
+
+/**
+ * <p>
+ * This class represents a determinate
+ * {@linkplain javax.measure.quantity.Quantity quantity} (as of length, time,
+ * heat, or value) adopted as a standard of measurement.
+ * </p>
+ * 
+ * <p>
+ * It is helpful to think of instances of this class as recording the history by
+ * which they are created. Thus, for example, the string "g/kg" (which is a
+ * dimensionless unit) would result from invoking the method toString() on a
+ * unit that was created by dividing a gram unit by a kilogram unit. Yet, "kg"
+ * divided by "kg" returns {@link #ONE} and not "kg/kg" due to automatic unit
+ * factorization.
+ * </p>
+ * 
+ * <p>
+ * This class supports the multiplication of offsets units. The result is
+ * usually a unit not convertible to its {@linkplain #toMetric metric unit}.
+ * Such units may appear in derivative quantities. For example Celsius per meter
+ * is an unit of gradient, which is common in atmospheric and oceanographic
+ * research.
+ * </p>
+ * 
+ * <p>
+ * Units raised at non-integral powers are not supported. For example,
+ * <code>LITRE.root(2)</code> raises an <code>ArithmeticException</code>; but
+ * <code>LITRE.toMetric().root(2)</code> returns <code>METRE</code>.
+ * </p>
+ * 
+ * <p>
+ * Instances of this class and sub-classes are immutable.
+ * </p>
+ * 
+ * @param <Q>
+ *            The type of the quantity measured by this unit.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:steve@unidata.ucar.edu">Steve Emmerson</a>
+ * @author <a href="mailto:desruisseaux@users.sourceforge.net">Martin
+ *         Desruisseaux</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * 
+ * @version 1.7 ($Revision: 312 $), $Date: 2011-03-07 00:50:44 +0430 $
+ * @see <a href="http://en.wikipedia.org/wiki/Units_of_measurement"> Wikipedia:
+ *      Units of measurement</a>
+ */
+public abstract class AbstractUnit<Q extends Quantity<Q>> extends MeasureUnit
+		implements Unit<Q>, IName, ISymbol {
+
+	/**
+	 * For cross-version compatibility.
+	 */
+	@SuppressWarnings("unused")
+	private static final long serialVersionUID = -2107517222666572443L;
+
+	/**
+	 * Holds the name.
+	 */
+	private String name;
+
+	/**
+	 * Holds the dimensionless unit <code>ONE</code>.
+	 */
+	public static final Unit<Dimensionless> ONE = new ProductUnit<Dimensionless>();
+
+	/**
+	 * Holds the unique symbols collection (base unit or alternate units).
+	 */
+	protected static final HashMap<String, Unit<?>> SYMBOL_TO_UNIT = new HashMap<String, Unit<?>>();
+
+	/**
+	 * Default constructor.
+	 */
+	protected AbstractUnit() {
+		this(null);
+	}
+
+	/**
+	 * Named constructor.
+	 */
+	@SuppressWarnings("deprecation")
+	protected AbstractUnit(String name) {
+		super();
+		this.name = name;
+	}
+
+	void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Returns the symbol (if any) of this unit. The default implementation
+	 * returns <code>null</code> (no symbol).
+	 * 
+	 * @return this unit symbol or <code>null</code> if this unit has not
+	 *         specific symbol associated with (e.g. product of units).
+	 */
+	public String getSymbol() {
+		return null;
+	}
+
+	/**
+	 * Returns the simple units and their exponent whose product is this unit or
+	 * <code>null</code> if this unit is a simple unit (not a product of
+	 * existing units).
+	 * 
+	 * @return the simple units and their exponent making up this unit.
+	 */
+	public Map<Unit<?>, Integer> getProductUnits() {
+		return null;
+	}
+
+	// ////////////////////////////////////////////////////
+	// Contract methods (for sub-classes to implement). //
+	// ////////////////////////////////////////////////////
+	/**
+	 * Returns the unscaled metric unit from which this unit is derived.
+	 * <p>
+	 * Metric units are either {@link BaseUnit base units}, {@link #alternate
+	 * alternate units} or product of rational powers of metric units.
+	 * </p>
+	 * <p>
+	 * Because the metric unit is unique by quantity type, it can be be used to
+	 * identify the quantity given the unit. For example:[code] static boolean
+	 * isAngularVelocity(Unit<?> unit) { return
+	 * unit.toMetric().equals(RADIAN.divide(SECOND)); }
+	 * assert(REVOLUTION.divide(MINUTE).isAngularVelocity()); // Returns true.
+	 * [/code]
+	 * 
+	 * @return the metric unit this unit is derived from or <code>this</code> if
+	 *         this unit {@link #isMetric() is a metric} unit.
+	 * @see #isMetric()
+	 */
+	protected abstract Unit<Q> toMetric();
+
+	/**
+	 * Returns the converter to the metric unit.
+	 * 
+	 * <p>
+	 * <i> Note: Having the same metric unit is not sufficient to ensure that a
+	 * converter exists between the two units (e.g. °C/m and K/m).</i>
+	 * </p>
+	 * 
+	 * @return the unit converter from this unit to its metric unit.
+	 */
+	public abstract UnitConverter getConverterToMetric();
+
+	/**
+	 * Returns the hash code for this unit.
+	 * 
+	 * @return this unit hashcode value.
+	 */
+	@Override
+	public abstract int hashCode();
+
+	/**
+	 * Indicates if the specified unit can be considered equals to the one
+	 * specified.
+	 * 
+	 * @param that
+	 *            the object to compare to.
+	 * @return <code>true</code> if this unit is considered equal to that unit;
+	 *         <code>false</code> otherwise.
+	 */
+	@Override
+	public abstract boolean equals(Object that);
+
+	/**
+	 * Indicates if this unit is an unscaled metric unit. Metric units are
+	 * either {@link BaseUnit base units}, {@link #alternate alternate units} or
+	 * product of rational powers of metric units. Because metric units are
+	 * unscaled units, {@link SI#METRE METRE} is a metric units; but
+	 * <code>KILO(METRE)</code> is not.
+	 * 
+	 * @return <code>this.toMetric().equals(this)</code>
+	 * @see #toMetric()
+	 */
+	public boolean isUnscaledMetric() {
+		return toMetric().equals(this);
+	}
+
+	/**
+	 * Indicates if this unit is compatible with the unit specified. Units don't
+	 * need to be equals to be compatible. For example:[code] RADIAN.equals(ONE)
+	 * == false RADIAN.isCompatible(ONE) == true [/code]
+	 * 
+	 * @param that
+	 *            the other unit.
+	 * @return <code>this.getDimension().equals(that.getDimension())</code>
+	 * @see #getDimension()
+	 */
+	public final boolean isCompatible(Unit<?> that) {
+		return (this == that) || this.toMetric().equals(that.getSystemUnit())
+				|| (!"".equals(this.getDimension().toString()) && this //$NON-NLS-1$
+						.getDimension().equals(that.getDimension()));
+	}
+
+	/**
+	 * Casts this unit to a parameterized unit of specified nature or throw a
+	 * <code>ClassCastException</code> if the dimension of the specified
+	 * quantity and this unit's dimension do not match. For example:[code]
+	 * Unit<Velocity> C =
+	 * METRE.times(299792458).divide(SECOND).asType(Velocity.class); [/code]
+	 * 
+	 * @param <T>
+	 *            The type of the quantity measured by the unit.
+	 * @param type
+	 *            the quantity class identifying the nature of the unit.
+	 * @return this unit parameterized with the specified type.
+	 * @throws ClassCastException
+	 *             if the dimension of this unit is different from the specified
+	 *             quantity dimension.
+	 * @throws UnsupportedOperationException
+	 *             if the specified type is not recognized.
+	 */
+	@SuppressWarnings("unchecked")
+	public final <T extends Quantity<T>> Unit<T> asType(Class<T> type)
+			throws ClassCastException {
+		Unit<T> metricUnit = QuantityFactory.getInstance(type).getMetricUnit();
+		if ((metricUnit == null) || metricUnit.isCompatible(this))
+			return (Unit<T>) this;
+		throw new ClassCastException("The unit: " + this //$NON-NLS-1$
+				+ " is not of parameterized type " + type); //$NON-NLS-1$
+		// TODO use NLS
+	}
+
+	/**
+	 * Returns the dimension of this unit (depends upon the current dimension
+	 * {@linkplain DimensionImpl.Model model}).
+	 * 
+	 * @return the dimension of this unit for the current model.
+	 */
+	public Dimension getDimension() {
+		// All possible metric units (BaseUnit, AlternateUnit and ProductUnit)
+		// overrides this method.
+		return this.toMetric().getDimension();
+	}
+
+	/**
+	 * Returns the intrinsic dimensional transform of this unit (depends upon
+	 * the current {@linkplain DimensionImpl.Model model} for {@link BaseUnit}
+	 * instance). Metric units should override this method.
+	 * 
+	 * @return the intrinsic transformation of this unit relatively to its
+	 *         dimension.
+	 * @throws UnsupportedOperationException
+	 *             if this unit is a metric unit and it does not override this
+	 *             method.
+	 */
+	public UnitConverter getDimensionalTransform() {
+		// All possible metric units (BaseUnit, AlternateUnit and ProductUnit)
+		// overrides this method.
+		return this.getConverterToMetric().concatenate(
+				((AbstractUnit<Q>) this.toMetric()).getDimensionalTransform());
+	}
+
+	/**
+	 * Returns a converter of numeric values from this unit to another unit of
+	 * same type (convenience method not raising checked exception).
+	 * 
+	 * @param that
+	 *            the unit of same type to which to convert the numeric values.
+	 * @return the converter from this unit to <code>that</code> unit.
+	 * @throws UnconvertibleException
+	 *             if the converter cannot be constructed.
+	 */
+	public UnitConverter getConverterTo(Unit<Q> that)
+			throws UnconvertibleException {
+		return searchConverterTo(that);
+	}
+
+	/**
+	 * Returns a converter form this unit to the specified unit of type unknown.
+	 * This method can be used when the dimension of the specified unit is
+	 * unknown at compile-time or when the {@linkplain DimensionImpl.Model
+	 * dimensional model} allows for conversion between units of different type.
+	 * To convert to a unit having the same parameterized type,
+	 * {@link #getConverterTo(AbstractUnit)} is preferred (no checked exception
+	 * raised).
+	 * 
+	 * @param that
+	 *            the unit to which to convert the numeric values.
+	 * @return the converter from this unit to <code>that</code> unit.
+	 * @throws ConversionException
+	 *             if the units are not compatible (e.g.
+	 *             <code>!this.isCompatible(that)</code>).
+	 * @throws UnsupportedOperationException
+	 *             if the converter cannot be constructed.
+	 */
+	public UnitConverter getConverterToAny(Unit<?> that)
+			throws IncommensurableException, UnconvertibleException {
+		return ((this == that) || this.equals(that)) ? AbstractConverter.IDENTITY
+				: searchConverterTo(that);
+	}
+
+	@SuppressWarnings("unchecked")
+	private UnitConverter searchConverterTo(Unit<?> that)
+			throws UnconvertibleException {
+		// First we have find a common dimension to convert to.
+
+		// Try the SI unit.
+		Unit<Q> thisSI = this.toMetric();
+		Unit<?> thatSI = that.getSystemUnit();
+		if (thisSI.equals(thatSI))
+			return ((AbstractUnit<?>) that).getConverterToMetric().inverse()
+					.concatenate(this.getConverterToMetric());
+
+		// Use dimensional unit.
+		if (!thisSI.getDimension().equals(thatSI.getDimension()))
+			throw new UnconvertibleException(this + " is not compatible with " //$NON-NLS-1$
+					+ that);
+		UnitConverter thisTransform = ((AbstractUnit<?>) thisSI)
+				.getDimensionalTransform().concatenate(
+						this.getConverterToMetric());
+		@SuppressWarnings("rawtypes")
+		UnitConverter thatTransform = ((AbstractUnit<Dimensionless>) thatSI)
+				.getDimensionalTransform().concatenate(
+						((AbstractUnit) that).getConverterToMetric());
+		return thatTransform.inverse().concatenate(thisTransform);
+	}
+
+	/**
+	 * Returns a metric unit equivalent to this unscaled metric unit but used in
+	 * expressions to distinguish between quantities of a different nature but
+	 * of the same dimensions.
+	 * 
+	 * <p>
+	 * Examples of alternate units:[code] Unit<Angle> RADIAN =
+	 * ONE.alternate("rad"); Unit<Force> NEWTON =
+	 * METRE.times(KILOGRAM).divide(SECOND.pow(2)).alternate("N");
+	 * Unit<Pressure> PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa");
+	 * [/code]
+	 * </p>
+	 * 
+	 * @param <Q>
+	 *            the type of the quantity measured by the new alternate unit.
+	 * 
+	 * @param symbol
+	 *            the new symbol for the alternate unit.
+	 * @return the alternate unit.
+	 * @throws UnsupportedOperationException
+	 *             if this unit is not an unscaled metric unit.
+	 * @throws IllegalArgumentException
+	 *             if the specified symbol is already associated to a different
+	 *             unit.
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<Q> alternate(String symbol) {
+		return new AlternateUnit(symbol, this);
+	}
+
+	/**
+	 * Returns the unit derived from this unit using the specified converter.
+	 * The converter does not need to be linear. For example:[code]
+	 * Unit<Dimensionless> DECIBEL = Unit.ONE.transform( new
+	 * LogConverter(10).inverse().concatenate( new RationalConverter(1, 10)));
+	 * [/code]
+	 * 
+	 * @param operation
+	 *            the converter from the transformed unit to this unit.
+	 * @return the unit after the specified transformation.
+	 */
+	@SuppressWarnings("unchecked")
+	public final Unit<Q> transform(UnitConverter operation) {
+		if (this instanceof TransformedUnit) {
+			Unit<Q> tf = this;
+			Unit<?> parent = (Unit<?>) ((TransformedUnit<?>) tf)
+					.getParentUnit();
+			UnitConverter toParent = ((TransformedUnit<?>) tf).toParentUnit();
+			if (toParent == null)
+				return (Unit<Q>) parent;
+			UnitConverter toParentConcat = toParent.concatenate(operation);
+			if (toParentConcat == AbstractConverter.IDENTITY)
+				return (Unit<Q>) parent;
+			return new TransformedUnit<Q>((Unit<Q>) parent,
+					(AbstractConverter) toParentConcat);
+		}
+		if (operation == AbstractConverter.IDENTITY)
+			return this;
+		return new TransformedUnit<Q>(this, (AbstractConverter) operation);
+	}
+
+	/**
+	 * Returns the result of adding an offset to this unit. The returned unit is
+	 * convertible with all units that are convertible with this unit.
+	 * 
+	 * @param offset
+	 *            the offset added (expressed in this unit, e.g.
+	 *            <code>CELSIUS = KELVIN.add(273.15)</code>).
+	 * @return <code>this.transform(new AddConverter(offset))</code>
+	 */
+	public final Unit<Q> add(double offset) {
+		if (offset == 0)
+			return this;
+		return transform(new AddConverter(offset));
+	}
+
+	/**
+	 * Returns the result of multiplying this unit by an exact factor.
+	 * 
+	 * @param factor
+	 *            the exact scale factor (e.g.
+	 *            <code>KILOMETRE = METRE.multiply(1000)</code>).
+	 * @return <code>this.transform(new RationalConverter(factor, 1))</code>
+	 */
+	final Unit<Q> multiply(long factor) {
+		if (factor == 1)
+			return this;
+		return transform(new RationalConverter(BigInteger.valueOf(factor),
+				BigInteger.ONE));
+	}
+
+	/**
+	 * Returns the result of multiplying this unit by a an approximate factor.
+	 * 
+	 * @param factor
+	 *            the approximate factor (e.g.
+	 *            <code>ELECTRON_MASS = KILOGRAM.multiply(9.10938188e-31)</code>
+	 *            ).
+	 * @return <code>this.transform(new MultiplyConverter(factor))</code>
+	 */
+	public final Unit<Q> multiply(double factor) {
+		if (factor == 1)
+			return this;
+		return transform(new MultiplyConverter(factor));
+	}
+
+	/**
+	 * Returns the product of this unit with the one specified.
+	 * 
+	 * @param that
+	 *            the unit multiplicand.
+	 * @return <code>this * that</code>
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<?> multiply(Unit<?> that) {
+		if (this.equals(ONE))
+			return that;
+		if (that.equals(ONE))
+			return this;
+		if (this.isRationalFactor())
+			return that.transform(this.getConverterTo((Unit) ONE));
+		if (((AbstractUnit) that).isRationalFactor())
+			return this.transform(that.getConverterTo((Unit) ONE));
+		return ProductUnit.getProductInstance(this, (AbstractUnit<?>) that);
+	}
+
+	private boolean isRationalFactor() {
+		if (!(this instanceof TransformedUnit<?>))
+			return false;
+		TransformedUnit<Q> tu = (TransformedUnit<Q>) this;
+		return tu.getParentUnit().equals(ONE)
+				&& (tu.getConverterTo(tu.getSystemUnit()) instanceof RationalConverter);
+	}
+
+	/**
+	 * Returns the inverse of this unit.
+	 * 
+	 * @return <code>1 / this</code>
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public final Unit<?> inverse() {
+		if (this.equals(ONE))
+			return this;
+		if (this.isRationalFactor())
+			return this.transform(this.getConverterTo((Unit) ONE).inverse());
+		return ProductUnit.getQuotientInstance((AbstractUnit<?>) ONE, this);
+	}
+
+	/**
+	 * Returns the result of dividing this unit by an exact divisor.
+	 * 
+	 * @param divisor
+	 *            the exact divisor. (e.g.
+	 *            <code>QUART = GALLON_LIQUID_US.divide(4)</code>).
+	 * @return <code>this.transform(new RationalConverter(1 , divisor))</code>
+	 */
+	public final Unit<Q> divide(long divisor) {
+		if (divisor == 1)
+			return this;
+		return transform(new RationalConverter(BigInteger.ONE,
+				BigInteger.valueOf(divisor)));
+	}
+
+	/**
+	 * Returns the result of dividing this unit by an approximate divisor.
+	 * 
+	 * @param divisor
+	 *            the approximate divisor.
+	 * @return <code>this.transform(new MultiplyConverter(1.0 / divisor))</code>
+	 */
+	public final Unit<Q> divide(double divisor) {
+		if (divisor == 1)
+			return this;
+		return transform(new MultiplyConverter(1.0 / divisor));
+	}
+	
+	/**
+	 * Returns the logarithmic result of this unit.
+	 * 
+	 * @param base
+	 *            the logarithmic base.
+	 * @return <code>this.transform(new MultiplyConverter(1.0 / divisor))</code>
+	 */	
+	public final Unit<Q> log(double base) {
+		return transform(new LogConverter(base));
+	}
+
+	/**
+	 * Returns the quotient of this unit with the one specified.
+	 * 
+	 * @param that
+	 *            the unit divisor.
+	 * @return <code>this / that</code>
+	 */
+	public final Unit<?> divide(Unit<?> that) {
+		return (AbstractUnit<?>) this.multiply(that.inverse());
+	}
+
+	/**
+	 * Returns a unit equals to the given root of this unit.
+	 * 
+	 * @param n
+	 *            the root's order.
+	 * @return the result of taking the given root of this unit.
+	 * @throws ArithmeticException
+	 *             if <code>n == 0</code> or if this operation would result in
+	 *             an unit with a fractional exponent.
+	 */
+	public final Unit<?> root(int n) {
+		if (n > 0)
+			return ProductUnit.getRootInstance(this, n);
+		else if (n == 0)
+			throw new ArithmeticException("Root's order of zero"); //$NON-NLS-1$
+		else
+			// n < 0
+			return ONE.divide(this.root(-n));
+	}
+
+	/**
+	 * Returns a unit equals to this unit raised to an exponent.
+	 * 
+	 * @param n
+	 *            the exponent.
+	 * @return the result of raising this unit to the exponent.
+	 */
+	public final Unit<?> pow(int n) {
+		if (n > 0)
+			return this.multiply(this.pow(n - 1));
+		else if (n == 0)
+			return ONE;
+		else
+			// n < 0
+			return ONE.divide(this.pow(-n));
+	}
+
+	/**
+	 * Returns a unit instance that is defined from the specified character
+	 * sequence (text) using the {@linkplain AbstractFormat#getInstance default}
+	 * unit format (<a href="http://unitsofmeasure.org/">UCUM</a> based). This
+	 * method is capable of parsing any units representations produced by
+	 * {@link #toString()}. Locale-sensitive unit formatting and parsing are
+	 * handled by the {@link AbstractFormat} class and its subclasses.
+	 * 
+	 * <p>
+	 * This method can be used to parse dimensionless units.[code]
+	 * Unit<Dimensionless> PERCENT =
+	 * Unit.valueOf("100").inverse().asType(Dimensionless.class); [/code]
+	 * 
+	 * @param charSequence
+	 *            the character sequence to parse.
+	 * @return <code>UnitFormat.getInstance().parse(csq, new ParsePosition(0))</code>
+	 * @throws IllegalArgumentException
+	 *             if the specified character sequence cannot be correctly
+	 *             parsed (e.g. not UCUM compliant).
+	 */
+	public static Unit<?> valueOf(CharSequence charSequence) {
+		return LocalUnitFormatImpl.getInstance().parse(charSequence,
+				new ParsePosition(0));
+	}
+
+	// ////////////////////
+	// GENERAL CONTRACT //
+	// ////////////////////
+	/**
+	 * Returns the international <code>String</code> representation of this unit
+	 * (<a href="http://unitsofmeasure.org/">UCUM</a> based). The string
+	 * produced for a given unit is always the same; it is not affected by the
+	 * locale. This means that it can be used as a canonical string
+	 * representation for exchanging units, or as a key for a Hashtable, etc.
+	 * Locale-sensitive unit formatting and parsing is handled by
+	 * {@link AbstractFormat} class and its subclasses.
+	 * 
+	 * @return <code>UnitFormat.getInstance().format(this)</code>
+	 */
+	@Override
+	public String toString() {
+		try {
+			UnitFormat format = LocalUnitFormatImpl.getInstance();
+			return String.valueOf(format
+					.format(this, new StringBuilder()));
+		} catch (IOException e) {
+			// TODO should this happen?
+			return ""; //$NON-NLS-1$
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Activator.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Activator.java
new file mode 100644
index 0000000..4520aed
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Activator.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import org.eclipse.uomo.units.impl.format.UnitFormatServiceImpl;
+import org.eclipse.uomo.units.impl.system.SystemOfUnitsServiceImpl;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.util.tracker.ServiceTracker;
+import org.unitsofmeasurement.service.UnitFormatService;
+import org.unitsofmeasurement.service.SystemOfUnitsService;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+
+/**
+ * OSGi part of implementation.
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.5.2 ($Revision: 215 $), $Date: 2010-09-19 22:12:08 +0200 (So, 19 Sep 2010) $
+ */
+public class Activator implements BundleActivator, ServiceListener {
+	private SystemOfUnitsService souService;
+	private ServiceTracker souServiceTracker;
+	private UnitFormatService formatService;
+	private ServiceTracker formatServiceTracker;
+	private BundleContext fContext;
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		fContext = context;
+		
+		// register the services
+		startFormat(context, null);
+		startSOU(context, null);
+//		startDictionary(context, props);
+	}
+	
+	private void startFormat(BundleContext context, Dictionary<String, ?> props) throws Exception {
+		formatService = new UnitFormatServiceImpl();
+		
+		// register the service
+		context.registerService(UnitFormatService.class.getName(), formatService, props);
+
+		// create a tracker and track the service
+		formatServiceTracker = new ServiceTracker(context, UnitFormatService.class.getName(), null);
+		formatServiceTracker.open();
+
+		// have a service listener to implement the whiteboard pattern
+	    fContext.addServiceListener(this, "(objectclass=" + Locale.class.getName() + ")");
+		
+		// grab the service
+//		formatService = (LocalFormatService) formatServiceTracker.getService();
+		
+		// register the locale
+//		formatService.registerDictionary(new DictionaryImpl());
+	}
+	
+	private void startSOU(BundleContext context, Dictionary<String, ?> props) throws Exception {
+		souService = new SystemOfUnitsServiceImpl();
+		
+		// register the service
+		context.registerService(SystemOfUnitsService.class.getName(), souService, props);
+
+		// create a tracker and track the service
+		souServiceTracker = new ServiceTracker(context, SystemOfUnitsService.class.getName(), null);
+		souServiceTracker.open();
+
+		// have a service listener to implement the whiteboard pattern
+	    fContext.addServiceListener(this, "(objectclass=" + SystemOfUnits.class.getName() + ")");
+		
+		// grab the service
+//		formatService = (LocalFormatService) formatServiceTracker.getService();
+		
+	}	
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		// close the service tracker(s)
+		stopFormat();
+		stopSOU();
+//		stopDictionary();
+		fContext = null;
+	}
+	
+	private void stopFormat() throws Exception {
+		formatServiceTracker.close();
+		formatServiceTracker = null;
+
+		formatService = null;
+	}
+	
+	private void stopSOU() throws Exception {
+		souServiceTracker.close();
+		souServiceTracker = null;
+
+		souService = null;
+	}
+
+	public void serviceChanged(ServiceEvent ev) {
+//		ServiceReference sr = ev.getServiceReference();
+		switch(ev.getType()) {
+			case ServiceEvent.REGISTERED:
+			{
+//				Dictionary dictionary = (Dictionary) fContext.getService(sr);
+//				dictService.registerDictionary(dictionary);
+			}
+			break;
+			case ServiceEvent.UNREGISTERING:
+			{
+//				Dictionary dictionary = (Dictionary) fContext.getService(sr);
+//				dictService.unregisterDictionary(dictionary);
+			}
+			break;
+		}
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/BinaryPrefix.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/BinaryPrefix.java
new file mode 100644
index 0000000..d76b8d6
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/BinaryPrefix.java
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+// ///////////////////
+// BINARY PREFIXES  //
+// ///////////////////
+/**
+ * Utility class holding binary prefixes.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ * @see <a href="http://en.wikipedia.org/wiki/Binary_prefix">Wikipedia: Binary
+ *      Prefix</a>
+ */
+public final class BinaryPrefix {
+
+	private BinaryPrefix() {
+		// Utility class no visible constructor.
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>10</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1024)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> KIBI(Unit<?> unit) {
+		return unit.multiply(K);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>20</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1048576)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> MEBI(Unit<?> unit) {
+		return unit.multiply(K2);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>30</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1073741824)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<?> GIBI(Unit<?> unit) {
+		return unit.multiply(K3);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>40</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1099511627776L)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> TEBI(Unit<?> unit) {
+		return unit.multiply(1099511627776L);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>50</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1125899906842624L)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> PEBI(Unit<?> unit) {
+		return unit.multiply(1125899906842624L);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>60</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1152921504606846976L)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> EXBI(Unit<?> unit) {
+		return unit.multiply(1152921504606846976L);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>70</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.transform(2<sup>70</sup>)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> ZEBI(Unit<?> unit) {
+		return unit.transform(K70);
+	}
+
+	/**
+	 * Returns the specified unit multiplied by the factor
+	 * <code>2<sup>80</sup></code> (binary prefix).
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.transform(2<sup>80</sup>)</code>.
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> YOBI(Unit<?> unit) {
+		return unit.transform(K80);
+	}
+
+	// ///////////////////
+	//  JDEC PREFIXES   //
+	// ///////////////////
+	
+	/**
+	 * <p>
+	 * kilo (K)
+	 * </p>
+	 * This JEDEC prefix is equivalent to <{@link #KIBI}>.
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1024)</code>.
+	 * @see <a
+	 *      href="http://en.wikipedia.org/wiki/JEDEC_memory_standards">Wikipedia:
+	 *      JEDEC memory standards</a>
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> JEDEC_KILO(Unit<?> unit) {
+		return unit.multiply(K);
+	}
+
+	/**
+	 * <p>
+	 * mega (M)
+	 * </p>
+	 * This JEDEC prefix is equal to <{@link #MEBI}>.
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1048576)</code>.
+	 * @see <a
+	 *      href="http://en.wikipedia.org/wiki/JEDEC_memory_standards">Wikipedia:
+	 *      JEDEC memory standards</a>
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> JEDEC_MEGA(Unit<?> unit) {
+		return unit.multiply(K2);
+	}
+
+	/**
+	 * <p>
+	 * giga (G)
+	 * </p>
+	 * This JEDEC prefix is equal to <{@link #GIBI}>.
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1073741824)</code>.
+	 * @see <a
+	 *      href="http://en.wikipedia.org/wiki/JEDEC_memory_standards">Wikipedia:
+	 *      JEDEC memory standards</a>
+	 */
+	public static <Q extends Quantity<Q>> Unit<?> JEDEC_GIGA(Unit<?> unit) {
+		return unit.multiply(K3);
+	}
+
+	// Holds prefix converters (optimization).
+	private static int K = 1024;
+
+	private static int K2 = 1048576;
+
+	private static int K3 = 1073741824;
+
+	private static RationalConverter K70 = new RationalConverter(BigInteger
+			.valueOf(2).pow(70), BigInteger.ONE);
+
+	private static RationalConverter K80 = new RationalConverter(BigInteger
+			.valueOf(2).pow(80), BigInteger.ONE);
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IMeasure.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IMeasure.java
new file mode 100644
index 0000000..a0ee031
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IMeasure.java
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2005, 2012, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p> This interface represents the IMeasure, countable, or comparable 
+ *     property or aspect of a thing.</p>
+ *     
+ * <p> Implementing instances are typically the result of a measurement:[code]
+ *         IMeasure<Mass> weight = BaseAmount.valueOf(180.0, POUND);
+ *     [/code]
+ *     They can also be created from custom classes:[code]
+ *     class Delay implements IMeasure<Duration> {
+ *          private long nanoSeconds; // Implicit internal unit.
+ *          public double doubleValue(Unit<Velocity> unit) { ... }
+ *          public long longValue(Unit<Velocity> unit) { ... }
+ *     }
+ *     Thread.wait(new Delay(24, HOUR)); // Assuming Thread.wait(IMeasure<Duration>) method.
+ *     [/code]</p>
+ *     
+ * <p> Although IMeasure instances are for the most part scalar quantities; 
+ *     more complex implementations (e.g. vectors, data set) are allowed as 
+ *     long as an aggregate magnitude can be determined. For example:[code]
+ *     class Velocity3D implements IMeasure<Velocity> {
+ *          private double x, y, z; // Meter per seconds.
+ *          public double doubleValue(Unit<Velocity> unit) { ... } // Returns vector norm.
+ *          ... 
+ *     }
+ *     class Sensors<Q extends Quantity> extends QuantityAmount<double[], Q> {
+ *          public doubleValue(Unit<Q> unit) { ... } // Returns median value. 
+ *          ...
+ *     } [/code]</p>
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 5.4.1, $Date: 2011-11-03 01:03:44 +0200 $
+ * @param <Q>
+ */
+public interface IMeasure<Q extends Quantity<Q>> extends Quantity<Q> {    
+        
+    /**
+     * Returns the sum of this amount with the one specified.
+     *
+     * @param  that the amount to be added.
+     * @return <code>this + that</code>.
+     */
+    IMeasure<Q> add(IMeasure<Q> that);
+    
+    /**
+     * Returns the difference between this amount and the one specified.
+     *
+     * @param  that the number to be subtracted.
+     * @return <code>this - that</code>.
+     */
+    IMeasure<Q> substract(IMeasure<Q> that);
+    
+    /**
+     * Returns the product of this amount with the one specified.
+     *
+     * @param  that the amount multiplier.
+     * @return <code>this · that</code>.
+     */
+    IMeasure<?> multiply(IMeasure<?> that);
+    
+    /**
+     * Returns the product of this amount with the number specified.
+     *
+     * @param  that the number multiplier.
+     * @return <code>this · that</code>.
+     */
+    IMeasure<?> multiply(Number that);
+    
+    /**
+     * Returns this amount divided by the one specified.
+     *
+     * @param  that the amount divisor.
+     * @return <code>this / that</code>.
+     */
+    IMeasure<?> divide(IMeasure<?> that);
+    
+    IMeasure<? extends IMeasure<Q>> inverse();
+    
+    /**
+     * Returns this measurement converted into another unit.
+     * 
+     * @param unit
+     * @return the converted result.
+     */
+    IMeasure<Q> to(Unit<Q> unit);
+    
+    /**
+     * Returns the value of this quantity as <code>double</code> stated
+     * in the specified unit. This method is recommended over <code>
+     * q.getUnit().getConverterTo(unit).convert(q.getValue()).doubleValue()</code>
+     *
+     * @param unit the unit in which the returned value is stated.
+     * @return the value of this quantity when stated in the specified unit.
+     */
+    public double doubleValue(Unit<Q> unit);
+    
+    /**
+     * Returns the value of this quantity as <code>long</code> stated
+     * in the specified unit. This method is recommended over <code>
+     * q.getUnit().getConverterTo(unit).convert(q.getValue()).longValue()</code>
+     *
+     * @param unit the unit in which the returned value is stated.
+     * @return the value of this quantity when stated in the specified unit.
+     */
+    public long longValue(Unit<Q> unit);
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IState.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IState.java
new file mode 100644
index 0000000..e2ac49f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IState.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import org.eclipse.uomo.core.IName;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.quantity.Time;
+
+/**
+ * Groups a state name, value and timestamp.
+ * The state itself is represented as a <type>Number</type> and the time is measured in IMeasure<Time>
+ * A State object is immutable so that it may be easily shared.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1, $Date: 2011-04-07 02:02:02 +0430 $
+ */
+public interface IState<Q extends Quantity<Q>> extends IName {
+	IMeasure<Time> time();
+	IMeasure<Q> value(); // TODO get* vs. getter-less, also avoid value().value()
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IndianPrefix.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IndianPrefix.java
new file mode 100644
index 0000000..93ae893
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/IndianPrefix.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Utility class holding prefixes used today in India, Pakistan, Bangladesh, Nepal
+ * and Myanmar (Burma); based on grouping by two decimal places, rather than the
+ * three decimal places common in most parts of the world. [code] import static
+ * org.eclipse.uomo.units.IndianPrefix.*; // Static import. ... Unit<Pressure>
+ * LAKH_PASCAL = LAKH(PASCAL);
+ * Unit<Length>CRORE_METER = CRORE(METER); [/code]
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/Indian_numbering_system">Wikipedia: Indian numbering system</a>
+ */
+public abstract class IndianPrefix {
+
+	/**
+	 * <p>
+	 * एक (Ek)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor <code>1</code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> EK(Unit<Q> unit) {
+		return unit;
+	}
+
+	/**
+	 * <p>
+	 * दस (Das)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>1</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(10)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> DAS(Unit<Q> unit) {
+		return unit.transform(E1);
+	}
+
+	/**
+	 * <p>
+	 * सौ (Sau)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>2</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(100)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> SAU(Unit<Q> unit) {
+		return unit.transform(E2);
+	}
+
+	/**
+	 * <p>
+	 * सहस्र (Sahasr)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>3</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e3)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> SAHASR(Unit<Q> unit) {
+		return unit.transform(E3);
+	}
+
+	/**
+	 * <p>
+	 * हजार (Hazaar)
+	 * </p>
+	 * Equivalent to {@link #SAHASR}.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> HAZAAR(Unit<Q> unit) {
+		return SAHASR(unit);
+	}
+
+	/**
+	 * <p>
+	 * लाख (Lakh)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>5</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e5)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> LAKH(Unit<Q> unit) {
+		return unit.transform(E5);
+	}
+
+	static final RationalConverter E5 = new RationalConverter(
+			BigInteger.TEN.pow(5), BigInteger.ONE);
+
+	/**
+	 * <p>
+	 * करोड़ (Crore)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>7</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e7)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> CRORE(Unit<Q> unit) {
+		return unit.transform(E7);
+	}
+
+	static final RationalConverter E7 = new RationalConverter(
+			BigInteger.TEN.pow(7), BigInteger.ONE);
+
+	/**
+	 * <p>
+	 * अरब (Arawb)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>9</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e9)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> ARAWB(Unit<Q> unit) {
+		return unit.transform(E9);
+	}
+
+	/**
+	 * <p>
+	 * खरब (Kharawb)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>11</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e11)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> KHARAWB(Unit<Q> unit) {
+		return unit.transform(E11);
+	}
+
+	/**
+	 * <p>
+	 * नील (Neel)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>13</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e13)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> NEEL(Unit<Q> unit) {
+		return unit.transform(E13);
+	}
+
+	/**
+	 * <p>
+	 * पद्म (Padma)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>15</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e15)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> PADMA(Unit<Q> unit) {
+		return unit.transform(E15);
+	}
+
+	/**
+	 * <p>
+	 * शंख (Shankh)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>17</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e17)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> SHANKH(Unit<Q> unit) {
+		return unit.transform(E17);
+	}
+
+	/**
+	 * <p>
+	 * महाशंख (Mahashankh)
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>19</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e19)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> MAHASHANKH(Unit<Q> unit) {
+		return unit.transform(E19);
+	}
+
+	// Holds prefix converters (optimization).
+	private static RationalConverter E19 = new RationalConverter(
+			BigInteger.TEN.pow(19), BigInteger.ONE);
+	private static RationalConverter E17 = new RationalConverter(
+			BigInteger.TEN.pow(17), BigInteger.ONE);
+	private static RationalConverter E15 = new RationalConverter(
+			BigInteger.TEN.pow(15), BigInteger.ONE);
+	private static RationalConverter E13 = new RationalConverter(
+			BigInteger.TEN.pow(13), BigInteger.ONE);
+	private static RationalConverter E11 = new RationalConverter(
+			BigInteger.TEN.pow(11), BigInteger.ONE);
+	private static RationalConverter E9 = new RationalConverter(
+			BigInteger.TEN.pow(9), BigInteger.ONE);
+	private static RationalConverter E3 = new RationalConverter(
+			BigInteger.TEN.pow(3), BigInteger.ONE);
+	private static RationalConverter E2 = new RationalConverter(
+			BigInteger.TEN.pow(2), BigInteger.ONE);
+	private static RationalConverter E1 = new RationalConverter(
+			BigInteger.TEN.pow(1), BigInteger.ONE);
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Messages.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Messages.java
new file mode 100644
index 0000000..964a0fa
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/Messages.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message class for unit messages. These messages are used throughout the
+ * package.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ */
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = Messages.class.getPackage()
+			.getName() + ".messages";//$NON-NLS-1$
+
+	private Messages() {
+	}
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+	public static String LocalFormat_Pattern;
+	public static String SI_A;
+	public static String SI_At;
+	public static String SI_bit;
+	public static String SI_Bq;
+	public static String SI_C;
+	public static String SI_cd;
+	public static String SI_F;
+	public static String SI_Gy;
+	public static String SI_H;
+	public static String SI_Hz;
+	public static String SI_J;
+	public static String SI_K;
+	public static String SI_kat;
+	public static String SI_kg;
+	public static String SI_kg_name;
+	public static String SI_lm;
+	public static String SI_lx;
+	public static String SI_m;
+	public static String SI_m_name;
+	public static String SI_mol;
+	public static String SI_N;
+	public static String SI_OhmS;
+	public static String SI_Pa;
+	public static String SI_rad;
+	public static String SI_s;
+	public static String SI_S;
+	public static String SI_Sv;
+	public static String SI_sr;
+	public static String SI_T;
+	public static String SI_V;
+	public static String SI_W;
+	public static String SI_Wb;
+	public static String US_lb_name;
+	public static String NonSI_R;
+	public static String NonSI_R_name;
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityAmount.java
new file mode 100644
index 0000000..a77880a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityAmount.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.unitsofmeasurement.quantity.Dimensionless;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.Measure;
+import com.ibm.icu.util.MeasureUnit;
+
+/**
+ * An amount of quantity, consisting of a Number and a Unit. QuantityAmount
+ * objects are immutable.
+ * 
+ * @see java.lang.Number
+ * @see MeasureUnit
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @param <Q>
+ *            The type of the quantity.
+ * @version 1.3.4 ($Revision: 212 $), $Date: 2011-09-12 01:20:44 +0200 (Mo, 12
+ *          Sep 2011) $ XXX rename to Amount, AbstractAmount or MeasureAmount?
+ *          FIXME Bug 338334 overwrite equals()
+ */
+public abstract class QuantityAmount<Q extends Quantity<Q>> extends Measure
+		implements IMeasure<Q> {
+
+	/**
+	 * Holds a dimensionless measure of one (exact).
+	 */
+	public static final Quantity<Dimensionless> ONE =
+			QuantityFactory.getInstance(Dimensionless.class).create(
+					BigDecimal.ONE, AbstractUnit.ONE);
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.ibm.icu.util.Measure#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null)
+			return false;
+		if (obj == this)
+			return true;
+		if (this.getClass() == obj.getClass()) {
+			return super.equals(obj);
+		} else {
+			if (obj instanceof Measure) {
+				Measure m = (Measure) obj;
+				if (m.getNumber().getClass() == this.getNumber().getClass()
+						&& m.getUnit().getClass() == this.unit().getClass()) {
+					return super.equals(obj);
+				} else {
+					// if (this.getQuantityUnit() instanceof AbstractUnit<?>) {
+					// if
+					// }
+					return super.equals(obj);
+				}
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * Indicates if this measure is exact.
+	 */
+	private boolean isExact;
+
+	/**
+	 * Holds the exact value (when exact) stated in this measure unit.
+	 */
+	// private long _exactValue;
+
+	/**
+	 * Holds the minimum value stated in this measure unit. For inexact
+	 * measures: _minimum < _maximum
+	 */
+	// private double _minimum;
+
+	/**
+	 * Holds the maximum value stated in this measure unit. For inexact
+	 * measures: _maximum > _minimum
+	 */
+	// private double _maximum;
+
+	protected QuantityAmount(Number number, MeasureUnit unit) {
+		super(number, unit);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.units.IMeasure#doubleValue(org.unitsofmeasurement.unit
+	 * .Unit)
+	 */
+	@Override
+	public double doubleValue(Unit<Q> unit) {
+		Unit<Q> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterTo(myUnit);
+			return converter.convert(getNumber().doubleValue());
+		} catch (UnconvertibleException e) {
+			throw e;
+		} // catch (IncommensurableException e) {
+		// throw new IllegalArgumentException(e.getMessage());
+		// }
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.uomo.units.IMeasure#longValue(org.unitsofmeasurement.unit
+	 * .Unit)
+	 */
+	@Override
+	public long longValue(Unit<Q> unit) {
+		Unit<Q> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterToAny(myUnit);
+			return (converter.convert(
+					BigDecimal.valueOf(getNumber().longValue()),
+					MathContext.DECIMAL128)).longValue();
+		} catch (UnconvertibleException e) {
+			throw e;
+		} catch (IncommensurableException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.unitsofmeasurement.quantity.Quantity#unit()
+	 */
+	@Override
+	public Unit<Q> unit() {
+		return internalUnit();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.unitsofmeasurement.quantity.Quantity#value()
+	 */
+	@Override
+	public Number value() {
+		return getNumber();
+	}
+
+	/**
+	 * Indicates if this measure amount is exact. An exact amount is guarantee
+	 * exact only when stated in this measure unit (e.g.
+	 * <code>this.longValue()</code>); stating the amount in any other unit may
+	 * introduce conversion errors.
+	 * 
+	 * @return <code>true</code> if this measure is exact; <code>false</code>
+	 *         otherwise.
+	 */
+	public boolean isExact() {
+		return isExact;
+	}
+
+	// ////////////////////
+	// Factory Creation //
+	// ////////////////////
+	
+//	private static <Q extends Quantity<Q>> QuantityAmount<Q> create(Number value, Unit<Q> unit) {
+//		
+//	}
+	
+
+//	@SuppressWarnings("unchecked")
+//	protected static <Q extends Quantity<Q>> QuantityAmount<Q> newInstance(
+//			Number value, Unit<?> unit) {
+//		QuantityAmount<Q> measure = FACTORY.create(value, unit);
+//
+//		measure._unit = (Unit<Q>) unit;
+//
+//		return measure;
+//	}
+
+	/**
+	 * Get the unit (convenience to avoid cast).
+	 * 
+	 * @provisional This API might change or be removed in a future release.
+	 */
+	@SuppressWarnings("unchecked")
+	private final AbstractUnit<Q> internalUnit() {
+		return (AbstractUnit<Q>) super.getUnit();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityFactory.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityFactory.java
new file mode 100644
index 0000000..210d1fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/QuantityFactory.java
@@ -0,0 +1,273 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import static org.eclipse.uomo.units.SI.*;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.unitsofmeasurement.quantity.*;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.util.TimeUnitAmount;
+
+/**
+ * A factory producing simple quantities instances (tuples {@link Number}/{@link AbstractUnit}).
+ *
+ * For example:[code]
+ *      Mass m = QuantityFactory.getInstance(Mass.class).create(23.0, KILOGRAM); // 23.0 kg
+ *      Time m = QuantityFactory.getInstance(Time.class).create(124, MILLI(SECOND)); // 124 ms
+ * [/code]
+ * @param <Q> The type of the quantity.
+ *
+ * @author  <a href="mailto:desruisseaux@users.sourceforge.net">Martin Desruisseaux</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0.8 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+abstract class QuantityFactory<Q extends Quantity<Q>>  {
+
+    /**
+     * Holds the current instances.
+     */
+    @SuppressWarnings("rawtypes")
+	private static final ConcurrentHashMap<Class, QuantityFactory> INSTANCES = new ConcurrentHashMap<Class, QuantityFactory>();
+    
+    private static final Logger logger = Logger.getLogger(QuantityFactory.class.getName());
+    
+    private static final Level LOG_LEVEL = Level.FINE;
+    
+    /**
+     * Returns the default instance for the specified quantity type.
+     *
+     * @param <Q> The type of the quantity
+     * @param type the quantity type
+     * @return the quantity factory for the specified type
+     */
+    @SuppressWarnings("unchecked")
+	public static <Q extends Quantity<Q>>  QuantityFactory<Q> getInstance(final Class<Q> type) {
+        
+         logger.log(LOG_LEVEL, "Type: " + type + ": " + type.isInterface());
+         QuantityFactory<Q> factory;
+         if (!type.isInterface()) {
+        	 if (type != null && type.getInterfaces() != null & type.getInterfaces().length > 0) {
+	        	 logger.log(LOG_LEVEL, "Type0: " + type.getInterfaces()[0]);
+	             Class<?> type2 = type.getInterfaces()[0];
+	
+	             factory = INSTANCES.get(type2);
+	            if (factory != null) return factory;
+	            if (!QuantityAmount.class.isAssignableFrom(type2))
+	                // This exception is not documented because it should never happen if the
+	                // user don't try to trick the Java generic types system with unsafe cast.
+	                throw new ClassCastException();
+	            factory = new Default<Q>((Class<Q>)type2);
+	            INSTANCES.put(type2, factory);
+        	 } else {
+                 factory = INSTANCES.get(type);
+                 if (factory != null) return factory;
+                 if (!QuantityAmount.class.isAssignableFrom(type))
+                     // This exception is not documented because it should never happen if the
+                     // user don't try to trick the Java generic types system with unsafe cast.
+                     throw new ClassCastException();
+                 factory = new Default<Q>(type);
+                 INSTANCES.put(type, factory);
+        	 }
+         } else {
+            factory = INSTANCES.get(type);
+            if (factory != null) return factory;
+            if (!Quantity.class.isAssignableFrom(type))
+                // This exception is not documented because it should never happen if the
+                // user don't try to trick the Java generic types system with unsafe cast.
+                throw new ClassCastException();
+            factory = new Default<Q>(type);
+            INSTANCES.put(type, factory);
+         }
+        return factory;
+    }
+
+    /**
+     * Overrides the default implementation of the factory for the specified
+     * quantity type.
+     *
+     * @param <Q> The type of the quantity
+     * @param type the quantity type
+     * @param factory the quantity factory
+     */
+    protected static <Q extends Quantity<Q>>  void setInstance(final Class<Q> type, QuantityFactory<Q> factory) {
+        if (!QuantityAmount.class.isAssignableFrom(type))
+            // This exception is not documented because it should never happen if the
+            // user don't try to trick the Java generic types system with unsafe cast.
+            throw new ClassCastException();
+        INSTANCES.put(type, factory);
+    }
+
+    /**
+     * Returns the quantity for the specified number stated in the specified unit.
+     *
+     * @param value the value stated in the specified unit
+     * @param unit the unit
+     * @return the corresponding quantity
+     */
+    public abstract Q create(Number value, Unit<Q> unit);
+
+    /**
+     * Returns the metric unit for quantities produced by this factory
+     * or <code>null</code> if unknown.
+     *
+     * @return the metric units for this factory quantities.
+     */
+    public abstract Unit<Q> getMetricUnit();
+    
+    /**
+     * The default factory implementation. This factory uses reflection for providing
+     * a default implementation for every {@link QuantityAmount} sub-types.
+     *
+     * @param <Q> The type of the quantity
+     */
+    private static final class Default<Q extends Quantity<Q>>  extends QuantityFactory<Q> {
+
+        /**
+         * The type of the quantities created by this factory.
+         */
+        private final Class<Q> type;
+
+        /**
+         * The metric unit for quantities created by this factory.
+         */
+        private final Unit<Q> metricUnit;
+
+        /**
+         * Creates a new factory for quantities of the given type.
+         *
+         * @param type The type of the quantities created by this factory.
+         */
+        @SuppressWarnings("unchecked")
+		Default(final Class<Q> type) {
+            this.type = type;
+            metricUnit = CLASS_TO_METRIC_UNIT.get(type);
+        }
+        @SuppressWarnings("rawtypes")
+		static final HashMap<Class, Unit> CLASS_TO_METRIC_UNIT = new HashMap<Class, Unit>();
+        static {
+            CLASS_TO_METRIC_UNIT.put(Dimensionless.class, AbstractUnit.ONE);
+            CLASS_TO_METRIC_UNIT.put(ElectricCurrent.class, AMPERE);
+            CLASS_TO_METRIC_UNIT.put(LuminousIntensity.class, CANDELA);
+            CLASS_TO_METRIC_UNIT.put(Temperature.class, KELVIN);
+            CLASS_TO_METRIC_UNIT.put(Mass.class, KILOGRAM);
+            CLASS_TO_METRIC_UNIT.put(Length.class, METRE);
+            CLASS_TO_METRIC_UNIT.put(AmountOfSubstance.class, MOLE);
+            CLASS_TO_METRIC_UNIT.put(TimeUnitAmount.class, SECOND);
+            CLASS_TO_METRIC_UNIT.put(MagnetomotiveForce.class, AMPERE_TURN);
+            CLASS_TO_METRIC_UNIT.put(Angle.class, RADIAN);
+            CLASS_TO_METRIC_UNIT.put(SolidAngle.class, STERADIAN);
+            CLASS_TO_METRIC_UNIT.put(Information.class, BIT);
+            CLASS_TO_METRIC_UNIT.put(Frequency.class, HERTZ);
+            CLASS_TO_METRIC_UNIT.put(Force.class, NEWTON);
+            CLASS_TO_METRIC_UNIT.put(Pressure.class, PASCAL);
+            CLASS_TO_METRIC_UNIT.put(Energy.class, JOULE);
+            CLASS_TO_METRIC_UNIT.put(Power.class, WATT);
+            CLASS_TO_METRIC_UNIT.put(ElectricCharge.class, COULOMB);
+            CLASS_TO_METRIC_UNIT.put(ElectricPotential.class, VOLT);
+            CLASS_TO_METRIC_UNIT.put(ElectricCapacitance.class, FARAD);
+            CLASS_TO_METRIC_UNIT.put(ElectricResistance.class, OHM);
+            CLASS_TO_METRIC_UNIT.put(ElectricConductance.class, SIEMENS);
+            CLASS_TO_METRIC_UNIT.put(MagneticFlux.class, WEBER);
+            CLASS_TO_METRIC_UNIT.put(MagneticFluxDensity.class, TESLA);
+            CLASS_TO_METRIC_UNIT.put(ElectricInductance.class, HENRY);
+            CLASS_TO_METRIC_UNIT.put(LuminousFlux.class, LUMEN);
+            CLASS_TO_METRIC_UNIT.put(Illuminance.class, LUX);
+            CLASS_TO_METRIC_UNIT.put(RadioactiveActivity.class, BECQUEREL);
+            CLASS_TO_METRIC_UNIT.put(RadiationDoseAbsorbed.class, GRAY);
+            CLASS_TO_METRIC_UNIT.put(RadiationDoseEffective.class, SIEVERT);
+            CLASS_TO_METRIC_UNIT.put(CatalyticActivity.class, KATAL);
+            CLASS_TO_METRIC_UNIT.put(Velocity.class, METRES_PER_SECOND);
+            CLASS_TO_METRIC_UNIT.put(Acceleration.class, METRES_PER_SQUARE_SECOND);
+            CLASS_TO_METRIC_UNIT.put(Area.class, SQUARE_METRE);
+            CLASS_TO_METRIC_UNIT.put(Volume.class, CUBIC_METRE);
+        }
+ 
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Q create(final Number value, final Unit<Q> unit) {
+            //System.out.println("Type: " + type);
+            return (Q) Proxy.newProxyInstance(type.getClassLoader(),
+                    new Class<?>[]{type}, new GenericHandler<Q>(value, unit));
+        }
+
+        @Override
+        public Unit<Q> getMetricUnit() {
+            return metricUnit;
+        }
+    }
+
+    /**
+     * The method invocation handler for implementation backed by any kind of {@link Number}.
+     * This is a fall back used when no specialized handler is available for the number type.
+     */
+    private static final class GenericHandler<Q extends Quantity<Q>>  implements InvocationHandler {
+        final Unit<Q> unit;
+        final Number value;
+
+        GenericHandler(final Number value, final Unit<Q> unit) {
+            this.unit = unit;
+            this.value = value;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object invoke(final Object proxy, final Method method, final Object[] args) {
+            final String name = method.getName();
+            if (name.equals("doubleValue")) { // Most frequent.
+	          final Unit<Q> toUnit = (Unit<Q>) args[0];
+	          if ((toUnit == unit) || (toUnit.equals(unit)))
+	                return value.doubleValue(); // Returns value directly.
+                  return unit.getConverterTo(toUnit).convert(value.doubleValue());
+            } else if (name.equals("longValue")) { 
+	          final Unit<Q> toUnit = (Unit<Q>) args[0];
+	          if ((toUnit == unit) || (toUnit.equals(unit)))
+	                return value.longValue(); // Returns value directly.
+                  double doubleValue = unit.getConverterTo(toUnit).convert(value.doubleValue());
+                  if ((doubleValue < Long.MIN_VALUE) || (doubleValue > Long.MAX_VALUE))
+                      throw new ArithmeticException("Overflow: " + doubleValue + " cannot be represented as a long");
+                  return (long) doubleValue;                
+            } else if (name.equals("getValue")) {
+                 return value;
+            } else if (name.equals("getUnit")) {
+                return unit;
+            } else if (name.equals("toString")) {
+                final StringBuilder buffer = new StringBuilder();
+                return buffer.append(value).append(' ').append(unit).toString();
+            } else if (name.equals("hashCode")) {
+                return value.hashCode() * 31 + unit.hashCode();
+            } else if (name.equals("equals")) {
+                final Object obj = args[0];
+                if (!(obj instanceof QuantityAmount))
+                    return false;
+                final QuantityAmount<Q> that = (QuantityAmount<Q>) obj;
+                if (!unit.isCompatible((AbstractUnit<?>) that.unit()))
+                    return false;
+                return value.doubleValue() == (that).doubleValue(unit);
+            } else if (name.equals("compareTo")) {
+                final QuantityAmount<Q> that = (QuantityAmount<Q>) args[0];
+                return Double.compare(value.doubleValue(), that.doubleValue(unit));
+            } else {
+                throw new UnsupportedOperationException(name);
+            }
+        }
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SI.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SI.java
new file mode 100644
index 0000000..f27617a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SI.java
@@ -0,0 +1,750 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import static org.eclipse.uomo.units.AbstractUnit.ONE;
+
+import java.math.BigInteger;
+import org.eclipse.uomo.units.Messages;
+import org.eclipse.uomo.units.impl.AlternateUnit;
+import org.eclipse.uomo.units.impl.BaseUnit;
+import org.eclipse.uomo.units.impl.ProductUnit;
+import org.eclipse.uomo.units.impl.TransformedUnit;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.quantity.*;
+
+/**
+ * <p>
+ * This class contains SI (Système International d'Unités) base units, and
+ * derived units.
+ * </p>
+ * 
+ * <p>
+ * It also defines an inner class for the 20 SI prefixes used to form decimal
+ * multiples and submultiples of SI units. For example:[code] import static
+ * org.eclipse.uomo.units.SI.*; // Static import. ... Unit<Pressure> HECTOPASCAL
+ * = HECTO(PASCAL); Unit<Length> KILOMETRE = KILO(METRE); [/code]
+ * </p>
+ * 
+ * @noextend This class is not intended to be extended by clients.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.32 ($Revision: 232 $), $Date: 2011-09-11 14:50:08 +0200 $
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/International_System_of_Units">Wikipedia:
+ *      International System of Units</a>
+ */
+public final class SI extends AbstractSystemOfUnits {
+
+	/**
+	 * The singleton instance of {@code SI}.
+	 */
+	private static final SI INSTANCE = new SI();
+
+	/**
+	 * Returns the singleton instance of this class.
+	 * 
+	 * @return the SI (metric) system instance.
+	 */
+	public static final SystemOfUnits getInstance() {
+		return INSTANCE;
+	}
+
+	// //////////////
+	// BASE UNITS //
+	// //////////////
+	/**
+	 * The base unit for electric current quantities (<code>A</code>). The
+	 * Ampere is that constant current which, if maintained in two straight
+	 * parallel conductors of infinite length, of negligible circular
+	 * cross-section, and placed 1 meter apart in vacuum, would produce between
+	 * these conductors a force equal to 2 * 10-7 newton per meter of length. It
+	 * is named after the French physicist Andre Ampere (1775-1836).
+	 */
+	public static final Unit<ElectricCurrent> AMPERE = addUnit(new BaseUnit<ElectricCurrent>(
+			Messages.SI_A));
+
+	/**
+	 * The base unit for luminous intensity quantities (<code>cd</code>). The
+	 * candela is the luminous intensity, in a given direction, of a source that
+	 * emits monochromatic radiation of frequency 540 * 1012 hertz and that has
+	 * a radiant intensity in that direction of 1/683 watt per steradian
+	 * 
+	 * @see <a href="http://en.wikipedia.org/wiki/Candela"> Wikipedia:
+	 *      Candela</a>
+	 */
+	public static final Unit<LuminousIntensity> CANDELA = addUnit(new BaseUnit<LuminousIntensity>(
+			Messages.SI_cd));
+
+	/**
+	 * The base unit for thermodynamic temperature quantities (<code>K</code>).
+	 * The kelvin is the 1/273.16th of the thermodynamic temperature of the
+	 * triple point of water. It is named after the Scottish mathematician and
+	 * physicist William Thomson 1st Lord Kelvin (1824-1907)
+	 */
+	public static final Unit<Temperature> KELVIN = addUnit(new BaseUnit<Temperature>(
+			Messages.SI_K));
+
+	/**
+	 * The base unit for mass quantities (<code>kg</code>). It is the only SI
+	 * unit with a prefix as part of its name and symbol. The kilogram is equal
+	 * to the mass of an international prototype in the form of a
+	 * platinum-iridium cylinder kept at Sevres in France.
+	 * 
+	 * @see #GRAM
+	 */
+	public static final Unit<Mass> KILOGRAM = addUnit(new BaseUnit<Mass>(
+			Messages.SI_kg, Messages.SI_kg_name));
+
+	/**
+	 * The base unit for length quantities (<code>m</code>). One metre was
+	 * redefined in 1983 as the distance traveled by light in a vacuum in
+	 * 1/299,792,458 of a second.
+	 */
+	public static final Unit<Length> METRE = addUnit(new BaseUnit<Length>(
+			Messages.SI_m, Messages.SI_m_name));
+
+	/**
+	 * The base unit for amount of substance quantities (<code>mol</code>). The
+	 * mole is the amount of substance of a system which contains as many
+	 * elementary entities as there are atoms in 0.012 kilogram of carbon 12.
+	 */
+	public static final Unit<AmountOfSubstance> MOLE = addUnit(new BaseUnit<AmountOfSubstance>(
+			Messages.SI_mol));
+
+	/**
+	 * The base unit for time quantities (<code>s</code>). It is defined as the
+	 * duration of 9,192,631,770 cycles of radiation corresponding to the
+	 * transition between two hyperfine levels of the ground state of cesium
+	 * (1967 Standard).
+	 * 
+	 * FIXME this is not aligned with TimeUnit from ICU4J due to TimeUnit so far cannot be extended 
+	 */
+	public static final Unit<Time> SECOND = addUnit(new BaseUnit<Time>(
+			Messages.SI_s));
+	// //////////////////////////////
+	// SI DERIVED ALTERNATE UNITS //
+	// //////////////////////////////
+
+	/**
+	 * The unit for magnetomotive force (<code>At</code>).
+	 */
+	public static final Unit<MagnetomotiveForce> AMPERE_TURN = addUnit(new AlternateUnit<MagnetomotiveForce>(
+			Messages.SI_At, (AbstractUnit<?>) SI.AMPERE));
+
+	/**
+	 * The derived unit for mass quantities (<code>g</code>). The base unit for
+	 * mass quantity is {@link #KILOGRAM}.
+	 */
+	public static final Unit<Mass> GRAM = KILOGRAM.divide(1000);
+
+	/**
+	 * The unit for plane angle quantities (<code>rad</code>). One radian is the
+	 * angle between two radii of a circle such that the length of the arc
+	 * between them is equal to the radius.
+	 */
+	public static final Unit<Angle> RADIAN = addUnit(new AlternateUnit<Angle>(
+			Messages.SI_rad, AbstractUnit.ONE));
+
+	/**
+	 * The unit for solid angle quantities (<code>sr</code>). One steradian is
+	 * the solid angle subtended at the center of a sphere by an area on the
+	 * surface of the sphere that is equal to the radius squared. The total
+	 * solid angle of a sphere is 4*Pi steradians.
+	 */
+	public static final Unit<SolidAngle> STERADIAN = addUnit(new AlternateUnit<SolidAngle>(
+			Messages.SI_sr, AbstractUnit.ONE));
+
+	/**
+	 * The unit for binary information (<code>bit</code>).
+	 */
+	public static final Unit<Information> BIT = addUnit(new AlternateUnit<Information>(
+			Messages.SI_bit, AbstractUnit.ONE));
+
+	/**
+	 * The derived unit for frequency (<code>Hz</code>). A unit of frequency
+	 * equal to one cycle per second. After Heinrich Rudolf Hertz (1857-1894),
+	 * German physicist who was the first to produce radio waves artificially.
+	 */
+	public static final Unit<Frequency> HERTZ = addUnit(new AlternateUnit<Frequency>(
+			Messages.SI_Hz,
+			(AbstractUnit<?>) AbstractUnit.ONE.divide(SECOND)));
+
+	/**
+	 * The derived unit for force (<code>N</code>). One newton is the force
+	 * required to give a mass of 1 kilogram an Force of 1 metre per second per
+	 * second. It is named after the English mathematician and physicist Sir
+	 * Isaac Newton (1642-1727).
+	 */
+	public static final Unit<Force> NEWTON = addUnit(new AlternateUnit<Force>(
+			Messages.SI_N, (AbstractUnit<?>) METRE.multiply(KILOGRAM)
+					.divide(SECOND.pow(2))));
+
+	/**
+	 * The derived unit for pressure, stress (<code>Pa</code>). One pascal is
+	 * equal to one newton per square meter. It is named after the French
+	 * philosopher and mathematician Blaise Pascal (1623-1662).
+	 */
+	public static final Unit<Pressure> PASCAL = addUnit(new AlternateUnit<Pressure>(
+			Messages.SI_Pa, (AbstractUnit<?>) NEWTON.divide(METRE.pow(2))));
+
+	/**
+	 * The derived unit for energy, work, quantity of heat (<code>J</code>). One
+	 * joule is the amount of work done when an applied force of 1 newton moves
+	 * through a distance of 1 metre in the direction of the force. It is named
+	 * after the English physicist James Prescott Joule (1818-1889).
+	 */
+	public static final Unit<Energy> JOULE = addUnit(new AlternateUnit<Energy>(
+			Messages.SI_J, (AbstractUnit<?>) NEWTON.multiply(METRE)));
+
+	/**
+	 * The derived unit for power, radiant, flux (<code>W</code>). One watt is
+	 * equal to one joule per second. It is named after the British scientist
+	 * James Watt (1736-1819).
+	 */
+	public static final Unit<Power> WATT = addUnit(new AlternateUnit<Power>(
+			Messages.SI_W, (AbstractUnit<?>) JOULE.divide(SECOND)));
+
+	/**
+	 * The derived unit for electric charge, quantity of electricity (
+	 * <code>C</code>). One Coulomb is equal to the quantity of charge
+	 * transferred in one second by a steady current of one ampere. It is named
+	 * after the French physicist Charles Augustin de Coulomb (1736-1806).
+	 */
+	public static final Unit<ElectricCharge> COULOMB = addUnit(new AlternateUnit<ElectricCharge>(
+			Messages.SI_C, (AbstractUnit<?>) SECOND.multiply(AMPERE)));
+
+	/**
+	 * The derived unit for electric potential difference, electromotive force (
+	 * <code>V</code>). One Volt is equal to the difference of electric
+	 * potential between two points on a conducting wire carrying a constant
+	 * current of one ampere when the power dissipated between the points is one
+	 * watt. It is named after the Italian physicist Count Alessandro Volta
+	 * (1745-1827).
+	 */
+	public static final Unit<ElectricPotential> VOLT = addUnit(new AlternateUnit<ElectricPotential>(
+			Messages.SI_V, (AbstractUnit<?>) WATT.divide(AMPERE)));
+
+	/**
+	 * The derived unit for capacitance (<code>F</code>). One Farad is equal to
+	 * the capacitance of a capacitor having an equal and opposite charge of 1
+	 * coulomb on each plate and a potential difference of 1 volt between the
+	 * plates. It is named after the British physicist and chemist Michael
+	 * Faraday (1791-1867).
+	 */
+	public static final Unit<ElectricCapacitance> FARAD = addUnit(new AlternateUnit<ElectricCapacitance>(
+			Messages.SI_F, (AbstractUnit<?>) COULOMB.divide(VOLT)));
+
+	/**
+	 * The derived unit for electric resistance (<code>Ohm</code>). One Ohm is
+	 * equal to the resistance of a conductor in which a current of one ampere
+	 * is produced by a potential of one volt across its terminals. It is named
+	 * after the German physicist Georg Simon Ohm (1789-1854).
+	 */
+	public static final Unit<ElectricResistance> OHM = addUnit(new AlternateUnit<ElectricResistance>(
+			Messages.SI_OhmS, (AbstractUnit<?>) VOLT.divide(AMPERE)));
+
+	/**
+	 * The derived unit for electric conductance (<code>S</code>). One Siemens
+	 * is equal to one ampere per volt. It is named after the German engineer
+	 * Ernst Werner von Siemens (1816-1892).
+	 */
+	public static final Unit<ElectricConductance> SIEMENS = addUnit(new AlternateUnit<ElectricConductance>(
+			Messages.SI_S, (AbstractUnit<?>) AMPERE.divide(VOLT)));
+
+	/**
+	 * The derived unit for magnetic flux (<code>Wb</code>). One Weber is equal
+	 * to the magnetic flux that in linking a circuit of one turn produces in it
+	 * an electromotive force of one volt as it is uniformly reduced to zero
+	 * within one second. It is named after the German physicist Wilhelm Eduard
+	 * Weber (1804-1891).
+	 */
+	public static final Unit<MagneticFlux> WEBER = addUnit(new AlternateUnit<MagneticFlux>(
+			Messages.SI_Wb, (AbstractUnit<?>) VOLT.multiply(SECOND)));
+
+	/**
+	 * The derived unit for magnetic flux density (<code>T</code>). One Tesla is
+	 * equal equal to one weber per square metre. It is named after the
+	 * Serbian-born American electrical engineer and physicist Nikola Tesla
+	 * (1856-1943).
+	 */
+	public static final Unit<MagneticFluxDensity> TESLA = addUnit(new AlternateUnit<MagneticFluxDensity>(
+			Messages.SI_T, (AbstractUnit<?>) WEBER.divide(METRE.pow(2))));
+
+	/**
+	 * The derived unit for inductance (<code>H</code>). One Henry is equal to
+	 * the inductance for which an induced electromotive force of one volt is
+	 * produced when the current is varied at the rate of one ampere per second.
+	 * It is named after the American physicist Joseph Henry (1791-1878).
+	 */
+	public static final Unit<ElectricInductance> HENRY = addUnit(new AlternateUnit<ElectricInductance>(
+			Messages.SI_H, (AbstractUnit<?>) WEBER.divide(AMPERE)));
+
+	/**
+	 * The derived unit for Celsius temperature (<code>Cel</code>). This is a
+	 * unit of temperature such as the freezing point of water (at one
+	 * atmosphere of pressure) is 0 Cel, while the boiling point is 100 Cel.
+	 */
+	public static final Unit<Temperature> CELSIUS = addUnit(KELVIN.add(273.15));
+
+	/**
+	 * The derived unit for luminous flux (<code>lm</code>). One Lumen is equal
+	 * to the amount of light given out through a solid angle by a source of one
+	 * candela intensity radiating equally in all directions.
+	 */
+	public static final Unit<LuminousFlux> LUMEN = addUnit(new AlternateUnit<LuminousFlux>(
+			Messages.SI_lm, (AbstractUnit<?>) CANDELA.multiply(STERADIAN)));
+
+	/**
+	 * The derived unit for illuminance (<code>lx</code>). One Lux is equal to
+	 * one lumen per square metre.
+	 */
+	public static final Unit<Illuminance> LUX = addUnit(new AlternateUnit<Illuminance>(
+			Messages.SI_lx, (AbstractUnit<?>) LUMEN.divide(METRE.pow(2))));
+
+	/**
+	 * The derived unit for activity of a radionuclide (<code>Bq</code>). One
+	 * becquerel is the radiation caused by one disintegration per second. It is
+	 * named after the French physicist, Antoine-Henri Becquerel (1852-1908).
+	 */
+	public static final Unit<RadioactiveActivity> BECQUEREL = addUnit(new AlternateUnit<RadioactiveActivity>(
+			Messages.SI_Bq,
+			(AbstractUnit<?>) AbstractUnit.ONE.divide(SECOND)));
+
+	/**
+	 * The derived unit for absorbed dose, specific energy (imparted), kerma (
+	 * <code>Gy</code>). One gray is equal to the dose of one joule of energy
+	 * absorbed per one kilogram of matter. It is named after the British
+	 * physician L. H. Gray (1905-1965).
+	 */
+	public static final Unit<RadiationDoseAbsorbed> GRAY = addUnit(new AlternateUnit<RadiationDoseAbsorbed>(
+			Messages.SI_Gy, (AbstractUnit<?>) JOULE.divide(KILOGRAM)));
+
+	/**
+	 * The derived unit for dose equivalent (<code>Sv</code>). One Sievert is
+	 * equal is equal to the actual dose, in grays, multiplied by a
+	 * "quality factor" which is larger for more dangerous forms of radiation.
+	 * It is named after the Swedish physicist Rolf Sievert (1898-1966).
+	 */
+	public static final Unit<RadiationDoseEffective> SIEVERT = addUnit(new AlternateUnit<RadiationDoseEffective>(
+			Messages.SI_Sv, (AbstractUnit<?>) JOULE.divide(KILOGRAM)));
+
+	/**
+	 * The derived unit for catalytic activity (<code>kat</code>).
+	 */
+	public static final Unit<CatalyticActivity> KATAL = addUnit(new AlternateUnit<CatalyticActivity>(
+			Messages.SI_kat, (AbstractUnit<?>) MOLE.divide(SECOND)));
+	// ////////////////////////////
+	// SI DERIVED PRODUCT UNITS //
+	// ////////////////////////////
+
+	/**
+	 * The metric unit for velocity quantities (<code>m/s</code>).
+	 * 
+	 */
+	public static final Unit<Velocity> METRES_PER_SECOND = addUnit(new ProductUnit<Velocity>(
+			(AbstractUnit<?>) METRE.divide(SECOND)));
+
+	/**
+	 * The metric unit for acceleration quantities (<code>m/s2</code>).
+	 */
+	public static final Unit<Acceleration> METRES_PER_SQUARE_SECOND = addUnit(new ProductUnit<Acceleration>(
+			(AbstractUnit<?>) METRES_PER_SECOND.divide(SECOND)));
+
+	/**
+	 * The metric unit for area quantities (<code>m2</code>).
+	 */
+	public static final Unit<Area> SQUARE_METRE = addUnit(new ProductUnit<Area>(
+			(AbstractUnit<?>) METRE.multiply(METRE)));
+
+	/**
+	 * The metric unit for volume quantities (<code>m3</code>).
+	 */
+	public static final Unit<Volume> CUBIC_METRE = addUnit(new ProductUnit<Volume>(
+			(AbstractUnit<?>) SQUARE_METRE.multiply(METRE)));
+
+    /////////////////////////////////////////////////////////////////
+	// Units outside the SI that are accepted for use with the SI. //
+	/////////////////////////////////////////////////////////////////
+
+	/**
+	* A dimensionless unit accepted for use with SI units (standard name <code>%</code>).
+	*/
+	public static final TransformedUnit<Dimensionless> PERCENT
+	= new TransformedUnit<Dimensionless>(ONE, new RationalConverter(1, 100));
+	
+	// //////////
+	// Others //
+	// //////////
+	/**
+	 * A unit used to measure the ionizing ability of radiation (standard name
+	 * <code>Roentgen</code>).
+	 */
+	@SuppressWarnings("unchecked")
+	public static final Unit<IonizingRadiation> ROENTGEN = (Unit<IonizingRadiation>) addUnit(COULOMB.divide(KILOGRAM)
+			.multiply(2.58e-4), Messages.NonSI_R_name);
+	
+	public static class Prefix {
+
+		private Prefix() {
+			// Utility class no visible constructor.
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>24</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e24)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> YOTTA(Unit<Q> unit) {
+			return unit.transform(E24);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>21</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e21)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> ZETTA(Unit<Q> unit) {
+			return unit.transform(E21);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>18</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e18)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> EXA(Unit<Q> unit) {
+			return unit.transform(E18);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>15</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e15)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> PETA(Unit<Q> unit) {
+			return (AbstractUnit<Q>) unit.transform(E15);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>12</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e12)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> TERA(Unit<Q> unit) {
+			return unit.transform(E12);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>9</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e9)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> GIGA(Unit<Q> unit) {
+			return unit.transform(E9);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>6</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e6)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> MEGA(Unit<Q> unit) {
+			return unit.transform(E6);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>3</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e3)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> KILO(Unit<Q> unit) {
+			return unit.transform(E3);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>2</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e2)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> HECTO(AbstractUnit<Q> unit) {
+			return unit.transform(E2);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>1</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e1)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> DEKA(AbstractUnit<Q> unit) {
+			return unit.transform(E1);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-1</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-1)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> DECI(Unit<Q> unit) {
+			return unit.transform(Em1);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-2</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-2)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> CENTI(Unit<Q> unit) {
+			return unit.transform(Em2);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-3</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-3)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> MILLI(Unit<Q> unit) {
+			return unit.transform(Em3);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-6</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-6)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> MICRO(Unit<Q> unit) {
+			return unit.transform(Em6);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-9</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-9)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> NANO(Unit<Q> unit) {
+			return unit.transform(Em9);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-12</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-12)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> PICO(Unit<Q> unit) {
+			return unit.transform(Em12);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-15</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-15)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> FEMTO(Unit<Q> unit) {
+			return unit.transform(Em15);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-18</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-18)</code>.
+		 */
+		public static final <Q extends Quantity<Q>> Unit<Q> ATTO(Unit<Q> unit) {
+			return unit.transform(Em18);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-21</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-21)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> ZEPTO(AbstractUnit<Q> unit) {
+			return unit.transform(Em21);
+		}
+
+		/**
+		 * Returns the specified unit multiplied by the factor
+		 * <code>10<sup>-24</sup></code>
+		 * 
+		 * @param <Q>
+		 *            The type of the quantity measured by the unit.
+		 * @param unit
+		 *            any unit.
+		 * @return <code>unit.times(1e-24)</code>.
+		 */
+		public static <Q extends Quantity<Q>> Unit<Q> YOCTO(AbstractUnit<Q> unit) {
+			return unit.transform(Em24);
+		}
+
+		// Holds prefix converters (optimization).
+		private static final RationalConverter E24 = new RationalConverter(
+				BigInteger.TEN.pow(24), BigInteger.ONE);
+
+		private static final RationalConverter E21 = new RationalConverter(
+				BigInteger.TEN.pow(21), BigInteger.ONE);
+
+		private static final RationalConverter E18 = new RationalConverter(
+				BigInteger.TEN.pow(18), BigInteger.ONE);
+
+		private static final RationalConverter E15 = new RationalConverter(
+				BigInteger.TEN.pow(15), BigInteger.ONE);
+
+		private static final RationalConverter E12 = new RationalConverter(
+				BigInteger.TEN.pow(12), BigInteger.ONE);
+
+		private static final RationalConverter E9 = new RationalConverter(
+				BigInteger.TEN.pow(9), BigInteger.ONE);
+
+		private static final RationalConverter E6 = new RationalConverter(
+				BigInteger.TEN.pow(6), BigInteger.ONE);
+
+		private static final RationalConverter E3 = new RationalConverter(
+				BigInteger.TEN.pow(3), BigInteger.ONE);
+
+		private static final RationalConverter E2 = new RationalConverter(
+				BigInteger.TEN.pow(2), BigInteger.ONE);
+
+		private static final RationalConverter E1 = new RationalConverter(
+				BigInteger.TEN.pow(1), BigInteger.ONE);
+
+		private static final RationalConverter Em1 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(1));
+
+		private static final RationalConverter Em2 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(2));
+
+		private static final RationalConverter Em3 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(3));
+
+		private static final RationalConverter Em6 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(6));
+
+		private static final RationalConverter Em9 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(9));
+
+		private static final RationalConverter Em12 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(12));
+
+		private static final RationalConverter Em15 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(15));
+
+		private static final RationalConverter Em18 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(18));
+
+		private static final RationalConverter Em21 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(21));
+
+		private static final RationalConverter Em24 = new RationalConverter(
+				BigInteger.ONE, BigInteger.TEN.pow(24));
+	}
+
+	@Override
+	public String getName() {
+		return getClass().getSimpleName();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SymbolMap.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SymbolMap.java
new file mode 100644
index 0000000..b5eec39
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/SymbolMap.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Eric Russell - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import org.eclipse.uomo.units.impl.system.USCustomary;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This interface provides a set of mappings between
+ *     {@link Unit Units} and symbols (both ways),
+ *     and from {@link org.unitsofmeasurement.UnitConverter
+ *     UnitConverter}s to prefixes symbols (also both ways).</p>
+ *     
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author Eric Russell
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1 , $Date: 2011-01-11 $
+ */
+public interface SymbolMap {
+
+    /**
+     * Attaches a label to the specified unit. For example:[code]
+     *    symbolMap.label(DAY.multiply(365), "year");
+     *    symbolMap.label({@link USCustomary USCustomary}.FOOT, "ft");
+     * [/code]
+     *
+     * @param unit the unit to label.
+     * @param symbol the new symbol for the unit.
+     * @throws UnsupportedOperationException if setting a unit label
+     *         is not allowed.
+     */
+    void label(Unit<?> unit, String symbol);
+
+    /**
+     * Attaches an alias to the specified unit. Multiple aliases may be
+     * attached to the same unit. Aliases are used during parsing to
+     * recognize different variants of the same unit.[code]
+     *     symbolMap.alias({@link USCustomary USCustomary}.FOOT, "foot");
+     *     symbolMap.alias({@link USCustomary USCustomary}.FOOT, "feet");
+     *     symbolMap.alias({@link SI SI}.METER, "meter");
+     *     symbolMap.alias({@link SI SI}.METER, "metre");
+     * [/code]
+     *
+     * @param unit the unit to label.
+     * @param symbol the new symbol for the unit.
+     * @throws UnsupportedOperationException if setting a unit alias
+     *         is not allowed.
+     */
+    void alias(Unit<?> unit, String symbol);
+
+    /**
+     * Attaches a label to the specified prefix. For example:[code]
+     *    symbolMap.prefix(new RationalConverter(1000000000, 1), "G"); // GIGA
+     *    symbolMap.prefix(new RationalConverter(1, 1000000), "µ"); // MICRO
+     * [/code]
+     *
+     * @param cvtr the unit converter.
+     * @param prefix the prefix for the converter.
+     * @throws UnsupportedOperationException if setting a prefix
+     *         is not allowed.
+     */
+    void prefix(UnitConverter cvtr, String prefix);
+
+    /**
+     * Returns the unit for the specified symbol.
+     *
+     * @param symbol the symbol.
+     * @return the corresponding unit or <code>null</code> if none.
+     */
+    Unit<?> getUnit(String symbol);
+
+    /**
+     * Returns the symbol (label) for the specified unit.
+     *
+     * @param unit the corresponding symbol.
+     * @return the corresponding symbol or <code>null</code> if none.
+     */
+    String getSymbol(Unit<?> unit);
+
+    /**
+     * Returns the unit converter for the specified prefix.
+     *
+     * @param prefix the prefix symbol.
+     * @return the corresponding converter or <code>null</code> if none.
+     */
+    UnitConverter getConverter(String prefix);
+
+    /**
+     * Returns the prefix for the specified converter.
+     *
+     * @param converter the unit converter.
+     * @return the corresponding prefix or <code>null</code> if none.
+     */
+    String getPrefix(UnitConverter converter);
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/TamilPrefix.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/TamilPrefix.java
new file mode 100644
index 0000000..ed6069c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/TamilPrefix.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2005, 2012, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Utility class holding prefixes used today in parts of India and Sri Lanka;
+ * based on grouping by two decimal places, rather than the
+ * three decimal places common in most parts of the world.</br><code> import static
+ * org.eclipse.uomo.units.TamilPrefix.*; // Static import. ... Unit<Pressure>
+ * ONDRU_PASCAL = ONDRU(PASCAL); 
+ * Unit<Length> PATHU_METER = PATHU(METER); </code>
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2 ($Revision$), $Date: 2012-04-02 $
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/Tamil_units_of_measurement#Whole_numbers">Wikipedia:
+ *      Tamil units of measurement - Whole numbers</a>
+ */
+public abstract class TamilPrefix  {
+
+	/**
+	 * <p>
+	 * onRu
+	 * </p>
+	 * Returns the specified unit multiplied by the factor <code>1</code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> onRu(Unit<Q> unit) {
+		return unit;
+	}
+	
+	/**
+	 * <p>
+	 * patthu
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>1</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(10)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> patthu(Unit<Q> unit) {
+		return unit.transform(E1);
+	}
+
+	/**
+	 * <p>
+	 * nooRu
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>2</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(100)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> nooRu(Unit<Q> unit) {
+		return unit.transform(E2);
+	}
+
+	/**
+	 * <p>
+	 * aayiram
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>3</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e3)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> aayiram(Unit<Q> unit) {
+		return unit.transform(E3);
+	}
+
+	/**
+	 * <p>
+	 * nooRaayiram
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>5</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e5)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> nooRaayiram(Unit<Q> unit) {
+		return unit.transform(E5);
+	}
+
+	static final RationalConverter E5 = new RationalConverter(
+			BigInteger.TEN.pow(5), BigInteger.ONE);
+
+	/**
+	 * <p>
+	 * thoLLunn
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>9</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e9)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> thoLLunn(Unit<Q> unit) {
+		return unit.transform(E9);
+	}
+
+	/**
+	 * <p>
+	 * eegiyam
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>12</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e12)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> eegiyam(Unit<Q> unit) {
+		return unit.transform(E12);
+	}
+
+	/**
+	 * <p>
+	 * neLai
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>15</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e15)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> neLai(Unit<Q> unit) {
+		return unit.transform(E15);
+	}
+
+	/**
+	 * <p>
+	 * iLanji
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>18</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e18)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> iLanji(Unit<Q> unit) {
+		return unit.transform(E18);
+	}
+
+	/**
+	 * <p>
+	 * veLLam
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>20</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e20)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> veLLam(Unit<Q> unit) {
+		return unit.transform(E20);
+	}
+	
+	/**
+	 * <p>
+	 * aambal
+	 * </p>
+	 * Returns the specified unit multiplied by the factor
+	 * <code>10<sup>21</sup></code>
+	 * 
+	 * @param unit
+	 *            any unit.
+	 * @return <code>unit.times(1e21)</code>.
+	 */
+	public static final <Q extends Quantity<Q>> Unit<Q> aambal(Unit<Q> unit) {
+		return unit.transform(E21);
+	}
+	
+	public static final class Sanskrit {
+		/**
+		 * <p>
+		 * ONDRU -one
+		 * </p>
+		 * Sanskrit translation for {@link #onRu}.
+		 */
+		public static final <Q extends Quantity<Q>> Unit<Q> ONDRU (Unit<Q> unit) {
+			return onRu(unit);
+		}
+		
+		/**
+		 * <p>
+		 * PATHU -ten
+		 * </p>
+		 * Sanskrit translation for {@link #patthu}.
+		 */
+		public static final <Q extends Quantity<Q>> Unit<Q> PATHU(Unit<Q> unit) {
+			return patthu(unit);
+		}
+	}
+
+	// Holds prefix converters (optimization).
+	private static RationalConverter E21 = new RationalConverter(
+			BigInteger.TEN.pow(21), BigInteger.ONE);
+	private static RationalConverter E20 = new RationalConverter(
+			BigInteger.TEN.pow(20), BigInteger.ONE);
+	private static RationalConverter E18 = new RationalConverter(
+			BigInteger.TEN.pow(18), BigInteger.ONE);
+	private static RationalConverter E15 = new RationalConverter(
+			BigInteger.TEN.pow(15), BigInteger.ONE);
+	private static RationalConverter E12 = new RationalConverter(
+			BigInteger.TEN.pow(12), BigInteger.ONE);
+	private static RationalConverter E9 = new RationalConverter(
+			BigInteger.TEN.pow(9), BigInteger.ONE);
+	private static RationalConverter E3 = new RationalConverter(
+			BigInteger.TEN.pow(3), BigInteger.ONE);
+	private static RationalConverter E2 = new RationalConverter(
+			BigInteger.TEN.pow(2), BigInteger.ONE);
+	private static RationalConverter E1 = new RationalConverter(
+			BigInteger.TEN.pow(1), BigInteger.ONE);
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AlternateUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AlternateUnit.java
new file mode 100644
index 0000000..ff5c5fa
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AlternateUnit.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+
+/**
+ * <p> This class represents metric units used in expressions to distinguish
+ *     between quantities of a different nature but of the same dimensions.
+ *     Alternate units are always unscaled metric units.</p>
+ *
+ * <p> Instances of this class are created through the
+ *     {@link AbstractUnit#alternate(String)} method.</p>
+ *
+ * @param <Q> The type of the quantity measured by this unit.
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.1, $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public final class AlternateUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> {
+
+    /** The serialVersionUID */
+    private static final long serialVersionUID = -1234567854321234567L;
+
+	/**
+     * Holds the parent unit (a system unit).
+     */
+    private final Unit<?> parent;
+
+    /**
+     * Holds the parent unit (a system unit).
+     */
+    private final String symbol;
+
+    /**
+     * Creates an alternate unit for the specified unit identified by the
+     * specified name and symbol.
+     *
+     * @param symbol the symbol for this alternate unit.
+     * @param parent the system unit from which this alternate unit is
+     *        derived.
+     * @throws UnsupportedOperationException if the parent is not
+     *         an unscaled metric unit.
+     * @throws IllegalArgumentException if the specified symbol is
+     *         associated to a different unit.
+     */
+    @SuppressWarnings("rawtypes")
+	public AlternateUnit(String symbol, Unit<?> parent) {
+	this(symbol, (AbstractUnit)parent);
+    }
+    
+    
+    /**
+     * Creates an alternate unit for the specified unit identified by the
+     * specified name and symbol.
+     *
+     * @param symbol the symbol for this alternate unit.
+     * @param parent the system unit from which this alternate unit is
+     *        derived.
+     * @throws UnsupportedOperationException if the parent is not
+     *         an unscaled metric unit.
+     * @throws IllegalArgumentException if the specified symbol is
+     *         associated to a different unit.
+     */
+    public AlternateUnit(String symbol, AbstractUnit<?> parent) {
+        if (parent == null || !parent.isUnscaledMetric())
+            throw new UnsupportedOperationException(parent + " is not an unscaled metric unit");
+        this.parent = parent;
+        this.symbol = symbol;
+        // Checks if the symbol is associated to a different unit.
+        synchronized (AbstractUnit.SYMBOL_TO_UNIT) {
+            AbstractUnit<?> unit = (AbstractUnit<?>) AbstractUnit.SYMBOL_TO_UNIT.get(symbol);
+            if (unit == null) {
+                AbstractUnit.SYMBOL_TO_UNIT.put(symbol, this);
+                return;
+            }
+            if (unit instanceof AlternateUnit<?>) {
+                AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
+                if (symbol.equals(existingUnit.getSymbol()) && this.parent.equals(existingUnit.parent))
+                    return; // OK, same unit.
+            }
+            throw new IllegalArgumentException("Symbol " + symbol + " is associated to a different unit");
+        }
+    }
+
+    @Override
+    public String getSymbol() {
+        return symbol;
+    }
+    
+	@Override
+	public Unit<Q> getSystemUnit() {
+		return toMetric();
+	}
+	
+    @Override
+    protected final AbstractUnit<Q> toMetric() {
+        return this;
+    }
+
+    @Override
+    public final UnitConverter getConverterToMetric() {
+        return AbstractConverter.IDENTITY;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof AlternateUnit<?>))
+            return false;
+        AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
+        return this.symbol.equals(thatUnit.symbol); // Symbols are unique.
+    }
+
+    @Override
+    public Dimension getDimension() {
+        return parent.getDimension();
+    }
+
+    @SuppressWarnings("rawtypes")
+	@Override
+    public UnitConverter getDimensionalTransform() {
+        return ((AbstractUnit)parent).getDimensionalTransform();
+    }
+
+    @Override
+    public int hashCode() {
+        return symbol.hashCode();
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AnnotatedUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AnnotatedUnit.java
new file mode 100644
index 0000000..a281377
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/AnnotatedUnit.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import java.util.Map;
+
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This class represents an annotated unit. It  allows for unit specialization
+ *     and annotation without changing the unit semantic. For example:[code]
+ *        public class Size implements Length {
+ *             private double meters;
+ *             ...
+ *             public static class Unit extends AnnotatedUnit<Length> {
+ *                  private Unit(org.unitsofmeasure.Unit<Length> realUnit, String annotation) {
+ *                      super(actualUnit, annotation);
+ *                  }
+ *                  public static Size.Unit METER = new Size.Unit(SI.METRE, "size"); // Equivalent to SI.METRE
+ *                  public static Size.Unit INCH = new Size.Unit(NonSI.INCH, "size"); // Equivalent to NonSI.INCH
+ *             }
+ *        }[/code]</p>
+ * <p> Annotation are often written between curly braces behind units
+ *     but they do not change, for example "%{vol}", "kg{total}", or
+ *     "{RBC}" (for "red blood cells") are equivalent to "%", "kg", and "1"
+ *      respectively.</p>
+ *
+ * <p><b>Note:</b> This class supports the {@code UnitFormat} implementation {@code LocalFormat}, 
+ * hence it is currently part of the internal format API. If required and made public, it's possible
+ * to locate in the "unit" package.</p>    
+ *
+ * @param <Q> The type of the quantity measured by this unit.
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.1 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class AnnotatedUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Holds the annotation.
+     */
+    private final String annotation;
+
+    /**
+     * Holds the actual unit, never an annotated unit.
+     */
+    private final AbstractUnit<Q> actualUnit;
+
+    public AbstractUnit<Q> getActualUnit() {
+		return actualUnit;
+	}
+
+	/**
+     * Creates an annotated unit for the specified unit.
+     *
+     * @param actualUnit the real unit.
+     * @param annotation the annotation.
+     */
+    public AnnotatedUnit(AbstractUnit<Q> actualUnit, String annotation) {
+        this.actualUnit = (actualUnit instanceof AnnotatedUnit<?>)
+                ? ((AnnotatedUnit<Q>) actualUnit).actualUnit : actualUnit;
+        this.annotation = annotation;
+    }
+
+    /**
+     * Returns an annotated unit equivalent to this unit. The annotation
+     * does not change the unit semantic.
+     * Annotation are often written between curly braces behind units.
+     * For example, annotated units "%{vol}", "kg{total}", or "{RBC}"
+     * (for "red blood cells") are equivalent to "%", "kg", and "1" respectively.
+     *
+     * @param annotation the new symbol for the alternate unit.
+     * @return the alternate unit.
+     * @throws UnsupportedOperationException if this unit is not a metric unit.
+     * @throws IllegalArgumentException if the specified symbol is already
+     *         associated to a different unit.
+     */
+    public final AbstractUnit<Q> annotate(String annotation) {
+        return new AnnotatedUnit<Q>(this, annotation);
+    }
+    
+    /**
+     * Returns the annotation (if any) of this unit.
+     * The default implementation returns <code>null</code> (no annotation).
+     *
+     * @return this unit annotation or <code>null</code> if this unit has not
+     *         specific symbol associated with (e.g. product of units).
+     */
+    public String getAnnotation() {
+        return annotation;
+    }
+
+   @Override
+    public String getSymbol() {
+        return actualUnit.getSymbol();
+    }
+   
+	@Override
+	public Unit<Q> getSystemUnit() {
+		return toMetric();
+	}
+	
+    @Override
+    public Map<Unit<?>, Integer> getProductUnits() {
+        return actualUnit.getProductUnits();
+    }
+  
+   @Override
+    protected Unit<Q> toMetric() {
+        return actualUnit.getSystemUnit();
+    }
+
+    @Override
+    public UnitConverter getConverterToMetric() {
+        return actualUnit.getConverterToMetric();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof AnnotatedUnit<?>))
+            return false;
+        AnnotatedUnit<?> thatUnit = (AnnotatedUnit<?>) that;
+        return this.actualUnit.equals(thatUnit.actualUnit) &&
+                this.annotation.equals(thatUnit.annotation);
+    }
+
+    @Override
+    public int hashCode() {
+        return actualUnit.hashCode() + annotation.hashCode();
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseAmount.java
new file mode 100644
index 0000000..43f6c57
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseAmount.java
@@ -0,0 +1,289 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import static org.eclipse.uomo.core.impl.OutputHelper.println;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.QuantityAmount;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.Dimensionless;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.MeasureUnit;
+
+/**
+ * Represents a generic quantity amount.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3.3, $Date: 2013-05-21 $
+ */
+public class BaseAmount<Q extends Quantity<Q>> extends QuantityAmount<Q>
+		implements Comparable<BaseAmount<Q>> {
+
+	/**
+	 * @param number
+	 * @param unit
+	 */
+	public BaseAmount(Number number, Unit<Q> unit) {
+		super(number, (MeasureUnit) unit);
+	}
+
+	/**
+	 * Returns the amount corresponding to the specified value and unit.
+	 * 
+	 * @param value
+	 *            the value stated in the specified unit.
+	 * @param unit
+	 *            the unit in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+	public static <Q extends Quantity<Q>> BaseAmount<Q> valueOf(Number value,
+			Unit<Q> unit) {
+		BaseAmount<Q> amount = new BaseAmount<Q>(value, unit);
+		return amount;
+	}
+
+	/**
+	 * Holds a dimensionless measure of one (exact).
+	 */
+	protected static final BaseAmount<Dimensionless> ONE = new BaseAmount<Dimensionless>(
+			BigDecimal.ONE, AbstractUnit.ONE);
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public BaseAmount<Q> add(IMeasure<Q> that) {
+		final IMeasure<Q> thatToUnit = that.to(unit());
+		return new BaseAmount(this.value().doubleValue()
+				+ thatToUnit.value().doubleValue(), unit());
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	@Override
+	public BaseAmount<Q> substract(IMeasure<Q> that) {
+		final IMeasure<Q> thatToUnit = that.to(unit());
+		return new BaseAmount(this.getNumber().doubleValue()
+				- thatToUnit.value().doubleValue(), unit());
+
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public BaseAmount<Q> multiply(IMeasure<?> that) {
+		Unit<?> unit = unit().multiply(that.unit());
+		return (BaseAmount<Q>) valueOf((value().doubleValue() * that.value()
+				.doubleValue()), unit);
+	}
+	
+	@Override
+	public BaseAmount<?> multiply(Number that) {
+		return (BaseAmount<Q>) valueOf((value().doubleValue() * that
+				.doubleValue()), unit());	
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public BaseAmount<Q> divide(IMeasure<?> that) {
+		Unit<?> unit = unit().divide(that.unit());
+		return (BaseAmount<Q>) valueOf((value().doubleValue() / that.value()
+				.doubleValue()), unit);
+	}
+
+	@Override
+	public BaseAmount<Q> to(Unit<Q> unit) {
+		return to(unit, MathContext.DECIMAL128);
+	}
+
+	public BaseAmount<Q> to(Unit<Q> unit, MathContext ctx) {
+		if (this.unit().equals(unit))
+			return this;
+		UnitConverter cvtr = this.unit().getConverterTo(unit);
+		if (cvtr == AbstractConverter.IDENTITY)
+			return (BaseAmount<Q>) valueOf(this.value(), unit);
+		return (BaseAmount<Q>) valueOf(convert(this.value(), cvtr, ctx), unit);
+	}
+
+	// Try to convert the specified value.
+	private static Number convert(Number value, UnitConverter cvtr,
+			MathContext ctx) {
+		if (cvtr instanceof RationalConverter) { // Try converting through Field
+													// methods.
+			RationalConverter rCvtr = (RationalConverter) cvtr;
+			BigInteger dividend = rCvtr.getDividend();
+			BigInteger divisor = rCvtr.getDivisor();
+			if (dividend.abs().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+				throw new ArithmeticException("Multiplier overflow"); //$NON-NLS-1$
+			if (divisor.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+				throw new ArithmeticException("Divisor overflow"); //$NON-NLS-1$
+			if (value instanceof BigInteger || value instanceof Long || value instanceof Integer) {
+				return (value.longValue() * dividend.longValue())
+					/ (divisor.longValue());
+			} else {
+				return (value.doubleValue() * dividend.doubleValue())
+					/ (divisor.doubleValue());
+				// TODO use actual BigDecimal methods for BigDecimal
+			}
+		} else if (cvtr instanceof AbstractConverter.Compound
+				&& cvtr.isLinear()) { // Do it in two parts.
+			AbstractConverter.Compound compound = (AbstractConverter.Compound) cvtr;
+			Number firstConversion = convert(value, compound.getRight(), ctx);
+			Number secondConversion = convert(firstConversion,
+					compound.getLeft(), ctx);
+			return secondConversion;
+		} else { // Try using BigDecimal as intermediate.
+			BigDecimal decimalValue = BigDecimal.valueOf(value.doubleValue());
+			BigDecimal newValue = cvtr.convert(decimalValue, ctx);
+			return newValue;
+			// if (((FieldNumber)value) instanceof Decimal)
+			// return (N)((FieldNumber)Decimal.valueOf(newValue));
+			// if (((FieldNumber)value) instanceof Float64)
+			// return (N)((FieldNumber)Float64.valueOf(newValue.doubleValue()));
+			// throw new ArithmeticException(
+			// "Generic amount conversion not implemented for amount of type " +
+			// value.getClass());
+		}
+	}
+
+	/**
+	 * Returns this measure raised at the specified exponent.
+	 * 
+	 * @param exp
+	 *            the exponent.
+	 * @return <code>this<sup>exp</sup></code>
+	 */
+	@SuppressWarnings("unchecked")
+	public IMeasure<? extends IMeasure<Q>> pow(int exp) {
+		if (exp < 0)
+			return (IMeasure<? extends IMeasure<Q>>) this.pow(-exp).inverse();
+		if (exp == 0)
+
+			return (IMeasure<? extends IMeasure<Q>>) ONE;
+
+		IMeasure<? extends IMeasure<Q>> pow2 = (IMeasure<? extends IMeasure<Q>>) this;
+		IMeasure<? extends IMeasure<Q>> result = null;
+		while (exp >= 1) { // Iteration.
+
+			if ((exp & 1) == 1) {
+				result = (IMeasure<? extends IMeasure<Q>>) ((result == null) ? pow2
+						: result.multiply(pow2));
+
+			}
+
+			pow2 = (IMeasure<? extends IMeasure<Q>>) pow2.multiply(pow2);
+
+			exp >>>= 1;
+
+		}
+
+		return result;
+
+	}
+
+	public IMeasure<? extends IMeasure<Q>> inverse() {
+		@SuppressWarnings({ "rawtypes", "unchecked" })
+		final IMeasure<? extends IMeasure<Q>> m = new BaseAmount(value(),
+				unit().inverse());
+		return m;
+	}
+
+	@Override
+	public int compareTo(BaseAmount<Q> o) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null)
+			return false;
+		if (obj == this)
+			return true;
+		if (obj instanceof BaseAmount<?>) {
+			BaseAmount<?> ba = (BaseAmount<?>) obj;
+			if (this.unit().getClass() == ba.unit().getClass()) {
+				return super.equals(obj);
+			}
+			if (ba.unit() instanceof AlternateUnit<?>) {
+				AlternateUnit<?> baa = (AlternateUnit<?>) ba.unit();
+				if (this.unit() instanceof AlternateUnit<?>) {
+					return super.equals(obj);
+				} else if (this.unit() instanceof AnnotatedUnit<?>) {
+					AnnotatedUnit<?> au = (AnnotatedUnit<?>) this.unit();
+					println("Ann: " + au); //$NON-NLS-1$
+				} else if (this.unit() instanceof BaseUnit<?>) {
+					BaseUnit<?> bu = (BaseUnit<?>) this.unit();
+					println("Bas: " + bu); //$NON-NLS-1$
+				} else if (this.unit() instanceof ProductUnit<?>) {
+					ProductUnit<?> pu = (ProductUnit<?>) this.unit();
+					println("Pro: " + pu); //$NON-NLS-1$
+				} else if (this.unit() instanceof TransformedUnit<?>) {
+					TransformedUnit<?> tu = (TransformedUnit<?>) this.unit();
+					println("Tran: " + tu); //$NON-NLS-1$
+					if (tu.getParentUnit().equals(baa)) {
+						return true; // FIXME use number here, too
+					}
+				} else {
+					return super.equals(obj);
+				}
+			}
+			if (ba.unit() instanceof BaseUnit<?>) {
+				if (this.unit() instanceof AlternateUnit<?>) {
+					AlternateUnit<?> au = (AlternateUnit<?>) this.unit();
+					println("Alt: " + au); //$NON-NLS-1$
+				} else if (this.unit() instanceof AnnotatedUnit<?>) {
+					AnnotatedUnit<?> au = (AnnotatedUnit<?>) this.unit();
+					println("Ann: " + au); //$NON-NLS-1$
+				} else if (this.unit() instanceof BaseUnit<?>) {
+					return super.equals(obj);
+				} else if (this.unit() instanceof ProductUnit<?>) {
+					ProductUnit<?> pu = (ProductUnit<?>) this.unit();
+					println("Pro: " + pu); //$NON-NLS-1$
+				} else if (this.unit() instanceof TransformedUnit<?>) {
+					TransformedUnit<?> tu = (TransformedUnit<?>) this.unit();
+					println("Tran: " + tu); //$NON-NLS-1$
+				} else {
+					return super.equals(obj);
+				}
+			}
+			if (ba.unit() instanceof TransformedUnit<?>) {
+				TransformedUnit<?> bat = (TransformedUnit<?>) ba.unit();
+				if (this.unit() instanceof AlternateUnit<?>) {
+					AlternateUnit<?> au = (AlternateUnit<?>) this.unit();
+					println("Alt: " + au); //$NON-NLS-1$
+					if (bat.getParentUnit().equals(au)) {
+						return true;
+					}
+				} else if (this.unit() instanceof AnnotatedUnit<?>) {
+					AnnotatedUnit<?> au = (AnnotatedUnit<?>) this.unit();
+					System.out.println("Ann: " + au); //$NON-NLS-1$
+				} else if (this.unit() instanceof BaseUnit<?>) {
+					BaseUnit<?> bu = (BaseUnit<?>) this.unit();
+					println("Bas: " + bu); //$NON-NLS-1$
+				} else if (this.unit() instanceof ProductUnit<?>) {
+					ProductUnit<?> pu = (ProductUnit<?>) this.unit();
+					println("Pro: " + pu); //$NON-NLS-1$
+				} else if (this.unit() instanceof TransformedUnit<?>) {
+					return super.equals(obj);
+				} else {
+					return super.equals(obj);
+				}
+			}
+		}
+		return super.equals(obj);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseUnit.java
new file mode 100644
index 0000000..c470e91
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/BaseUnit.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import java.io.Serializable;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This class represents the building blocks on top of which all others
+ *     units are created. Base units are always unscaled metric units.</p>
+ * 
+ * <p> When using the {@linkplain Dimensional.Model#STANDARD standard} model
+ *     (default), all seven base units are dimensionally independent.</p>
+ *
+ * @param <Q> The type of the quantity measured by this unit.
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.10 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ * @see <a href="http://en.wikipedia.org/wiki/SI_base_unit">
+ *       Wikipedia: SI base unit</a>
+ */
+public class BaseUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> implements Serializable {
+    
+    /**
+     * Holds the symbol.
+     */
+    private final String symbol;
+
+    /** The serialVersionUID */
+    private static final long serialVersionUID = 1234567654321265167L;
+
+    /**
+     * Creates a base unit having the specified symbol.
+     *
+     * @param symbol the symbol of this base unit.
+     * @throws IllegalArgumentException if the specified symbol is
+     *         associated to a different unit.
+     */
+    public BaseUnit(String symbol, String name) {
+        super(name);
+    	this.symbol = symbol;
+        // Checks if the symbol is associated to a different unit.
+        synchronized (AbstractUnit.SYMBOL_TO_UNIT) {
+            Unit<?> unit = AbstractUnit.SYMBOL_TO_UNIT.get(symbol);
+            if (unit == null) {
+                AbstractUnit.SYMBOL_TO_UNIT.put(symbol, this);
+                return;
+            }
+            if (!(unit instanceof BaseUnit<?>))
+                throw new IllegalArgumentException("Symbol " + symbol + " is associated to a different unit");
+        }
+    }
+    
+    /**
+     * Creates a base unit having the specified symbol.
+     *
+     * @param symbol the symbol of this base unit.
+     * @throws IllegalArgumentException if the specified symbol is
+     *         associated to a different unit.
+     */
+    public BaseUnit(String symbol) {
+    	this(symbol, null);
+    }
+	
+    @Override
+    public String getSymbol() {
+        return symbol;
+    }
+    
+	@Override
+	public Unit<Q> getSystemUnit() {
+		return toMetric();
+	}
+	
+    @Override
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof BaseUnit<?>)) {
+        	if (!(that instanceof Unit<?>)) {
+        		return false;
+        	} else {
+        		if (that instanceof TransformedUnit<?>) {
+        			if (((TransformedUnit<?>) that).getParentUnit() instanceof BaseUnit<?>) {        				
+        				if(this.getSymbol().equals(((TransformedUnit<?>)that).getParentUnit().getSymbol())) {
+        					for (@SuppressWarnings("unused") UnitConverter comp : ((TransformedUnit<?>) that).toParentUnit().getCompoundConverters()) {
+        						// FIXME Bug 338334 evaluate factor 1 for TU
+//								System.out.println(comp.toString());
+							}
+        				}
+        			}
+        		}
+        		if (that instanceof ProductUnit<?>) {
+        			ProductUnit<?> pu = (ProductUnit<?>) that;
+//        			System.out.println("Product Unit: " + pu.getProductUnits());
+        			return this.symbol.equals(pu.getSymbol());
+        		}
+        		return false;
+        	}
+        }  else {        	
+	        BaseUnit<?> thatUnit = (BaseUnit<?>) that;
+	        return this.symbol.equals(thatUnit.symbol);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return symbol.hashCode();
+    }
+
+    @Override
+    protected Unit<Q> toMetric() {
+        return this;
+    }
+
+    @Override
+    public UnitConverter getConverterToMetric() {
+        return AbstractConverter.IDENTITY;
+    }
+
+    @Override
+    public Dimension getDimension() {
+        return DimensionImpl.getModel().getDimension(this);
+    }
+
+    @Override
+    public UnitConverter getDimensionalTransform() {
+        return DimensionImpl.getModel().getTransform(this);
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/DimensionImpl.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/DimensionImpl.java
new file mode 100644
index 0000000..75bafb7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/DimensionImpl.java
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.quantity.Dimensionless;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p>
+ * This class represents the dimension of an unit. Two units <code>u1</code> and
+ * <code>u2</code> are {@linkplain Unit#isCompatible compatible} if and only if
+ * <code>(u1.getDimension().equals(u2.getDimension())))</code>
+ * </p>
+ * 
+ * <p>
+ * Instances of this class are immutable.
+ * </p>
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * 
+ * @version 1.0.5, $Date: 2013-03-20 $
+ * @see <a href="http://www.bipm.org/en/si/si_brochure/chapter1/1-3.html"> BIPM:
+ *      SI Brochure Chapter 1.3</a>
+ */
+public final class DimensionImpl implements Dimension, Serializable {
+
+	/**
+	 * For cross-version compatibility.
+	 */
+	private static final long serialVersionUID = 2377803885472362640L;
+
+	/**
+	 * Holds the current physical model.
+	 */
+	private static Model model = Model.STANDARD;
+
+	/**
+	 * Holds dimensionless.
+	 */
+	public static final Dimension NONE = new DimensionImpl(AbstractUnit.ONE);
+
+	/**
+	 * Holds length dimension (L).
+	 */
+	public static final Dimension LENGTH = new DimensionImpl('L');
+
+	/**
+	 * Holds mass dimension (M).
+	 */
+	public static final Dimension MASS = new DimensionImpl('M');
+
+	/**
+	 * Holds time dimension (T).
+	 */
+	public static final Dimension TIME = new DimensionImpl('T');
+
+	/**
+	 * Holds electric current dimension (I).
+	 */
+	public static final Dimension ELECTRIC_CURRENT = new DimensionImpl('I');
+
+	/**
+	 * Holds temperature dimension (Θ). TODO use Theta again, currently not
+	 * working (Bug 351656)
+	 */
+	public static final Dimension TEMPERATURE = new DimensionImpl('Q');
+
+	/**
+	 * Holds amount of substance dimension (N).
+	 */
+	public static final Dimension AMOUNT_OF_SUBSTANCE = new DimensionImpl('N');
+
+	/**
+	 * Holds luminous intensity dimension (J).
+	 */
+	public static final Dimension LUMINOUS_INTENSITY = new DimensionImpl('J');
+
+	/**
+	 * Holds the pseudo unit associated to this dimension.
+	 */
+	private final Unit<?> pseudoUnit;
+
+	/**
+	 * Creates a new dimension associated to the specified symbol.
+	 * 
+	 * @param symbol
+	 *            the associated symbol.
+	 */
+	private DimensionImpl(char symbol) {
+		pseudoUnit = new BaseUnit<Dimensionless>("[" + symbol + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Creates a dimension having the specified pseudo-unit (base unit or
+	 * product of base unit).
+	 * 
+	 * @param pseudoUnit
+	 *            the pseudo-unit identifying this dimension.
+	 */
+	private DimensionImpl(Unit<?> pseudoUnit) {
+		this.pseudoUnit = pseudoUnit;
+	}
+
+	/**
+	 * Returns the product of this dimension with the one specified.
+	 * 
+	 * @param that
+	 *            the dimension multiplicand.
+	 * @return <code>this * that</code>
+	 */
+	@Override
+	public final Dimension multiply(Dimension that) {
+		return new DimensionImpl(
+				this.pseudoUnit.multiply(((DimensionImpl) that).pseudoUnit));
+	}
+
+	/**
+	 * Returns the quotient of this dimension with the one specified.
+	 * 
+	 * @param that
+	 *            the dimension divisor.
+	 * @return <code>this / that</code>
+	 */
+	public final Dimension divide(Dimension that) {
+		return new DimensionImpl(
+				this.pseudoUnit.divide(((DimensionImpl) that).pseudoUnit));
+	}
+
+	/**
+	 * Returns this dimension raised to an exponent.
+	 * 
+	 * @param n
+	 *            the exponent.
+	 * @return the result of raising this dimension to the exponent.
+	 */
+	public final Dimension pow(int n) {
+		return new DimensionImpl(this.pseudoUnit.pow(n));
+	}
+
+	/**
+	 * Returns the given root of this dimension.
+	 * 
+	 * @param n
+	 *            the root's order.
+	 * @return the result of taking the given root of this dimension.
+	 * @throws ArithmeticException
+	 *             if <code>n == 0</code>.
+	 */
+	public final Dimension root(int n) {
+		return new DimensionImpl(this.pseudoUnit.root(n));
+	}
+
+	/**
+	 * Returns the fundamental dimensions and their exponent whose product is
+	 * this dimension or <code>null</code> if this dimension is a fundamental
+	 * dimension.
+	 * 
+	 * @return the mapping between the fundamental dimensions and their
+	 *         exponent.
+	 */
+	public Map<Dimension, Integer> getProductDimensions() {
+		if (pseudoUnit == null)
+			return null;
+		@SuppressWarnings("unchecked")
+		Map<? extends Unit<?>, Integer> pseudoUnits = (Map<? extends Unit<?>, Integer>) pseudoUnit
+				.getProductUnits();
+		Map<Dimension, Integer> fundamentalDimensions = new HashMap<Dimension, Integer>();
+		for (Entry<? extends Unit<?>, Integer> entry : pseudoUnits.entrySet()) {
+			fundamentalDimensions.put(new DimensionImpl(entry.getKey()),
+					entry.getValue());
+		}
+		return fundamentalDimensions;
+	}
+
+	/**
+	 * Returns the representation of this dimension.
+	 * 
+	 * @return the representation of this dimension.
+	 */
+	@Override
+	public String toString() {
+		return String.valueOf(pseudoUnit);
+	}
+
+	/**
+	 * Indicates if the specified dimension is equals to the one specified.
+	 * 
+	 * @param that
+	 *            the object to compare to.
+	 * @return <code>true</code> if this dimension is equals to that dimension;
+	 *         <code>false</code> otherwise.
+	 */
+	@Override
+	public boolean equals(Object that) {
+		if (this == that)
+			return true;
+		return (that instanceof DimensionImpl)
+				&& pseudoUnit.equals(((DimensionImpl) that).pseudoUnit);
+	}
+
+	/**
+	 * Returns the hash code for this dimension.
+	 * 
+	 * @return this dimension hashcode value.
+	 */
+	@Override
+	public int hashCode() {
+		return pseudoUnit.hashCode();
+	}
+
+	/**
+	 * Sets the model used to determinate the units dimensions.
+	 * 
+	 * @param model
+	 *            the new model to be used when calculating unit dimensions.
+	 */
+	public static void setModel(Model model) {
+		DimensionImpl.model = model;
+	}
+
+	/**
+	 * Returns the model used to determinate the units dimensions (default
+	 * {@link Model#STANDARD STANDARD}).
+	 * 
+	 * @return the model used when calculating unit dimensions.
+	 */
+	public static Model getModel() {
+		return DimensionImpl.model;
+	}
+	
+	/**
+	 * Creates a new dimension associated to the specified symbol.
+	 * 
+	 * @param symbol
+	 *            the associated symbol.
+	 */
+	public static Dimension valueOf(char symbol) {
+		return new DimensionImpl(symbol);
+	}
+
+	/**
+	 * This interface represents the mapping between {@linkplain BaseUnit base
+	 * units} and {@linkplain DimensionImpl dimensions}. Custom models may allow
+	 * conversions not possible using the {@linkplain #STANDARD standard} model.
+	 * For example:[code] public static void main(String[] args) {
+	 * Dimension.Model relativistic = new Dimension.Model() { RationalConverter
+	 * metreToSecond = new RationalConverter(BigInteger.ONE,
+	 * BigInteger.valueOf(299792458)); // 1/c
+	 * 
+	 * public Dimension getDimension(BaseUnit unit) { if (unit.equals(METRE))
+	 * return Dimension.TIME; return
+	 * Dimension.Model.STANDARD.getDimension(unit); }
+	 * 
+	 * public UnitConverter getTransform(BaseUnit unit) { if
+	 * (unit.equals(METRE)) return metreToSecond; return
+	 * Dimension.Model.STANDARD.getTransform(unit); }};
+	 * Dimension.setModel(relativistic);
+	 * 
+	 * // Converts 1.0 GeV (energy) to kg (mass).
+	 * System.out.println(Unit.valueOf
+	 * ("GeV").getConverterTo(KILOGRAM).convert(1.0)); }
+	 * 
+	 * > 1.7826617302520883E-27[/code]
+	 */
+	public interface Model {
+
+		/**
+		 * Holds the standard model (default).
+		 */
+		public Model STANDARD = new Model() {
+
+			public Dimension getDimension(Unit<?> unit) {
+				if (unit.equals(SI.METRE))
+					return DimensionImpl.LENGTH;
+				if (unit.equals(SI.KILOGRAM))
+					return DimensionImpl.MASS;
+				if (unit.equals(SI.KELVIN))
+					return DimensionImpl.TEMPERATURE;
+				if (unit.equals(SI.SECOND))
+					return DimensionImpl.TIME;
+				if (unit.equals(SI.AMPERE))
+					return DimensionImpl.ELECTRIC_CURRENT;
+				if (unit.equals(SI.MOLE))
+					return DimensionImpl.AMOUNT_OF_SUBSTANCE;
+				if (unit.equals(SI.CANDELA))
+					return DimensionImpl.LUMINOUS_INTENSITY;
+				return new DimensionImpl(new BaseUnit<Dimensionless>(
+						"[" + unit.getSymbol() + "]")); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			public UnitConverter getTransform(Unit<?> unit) {
+				return AbstractConverter.IDENTITY;
+			}
+		};
+
+		/**
+		 * Returns the dimension of the specified base unit (a dimension
+		 * particular to the base unit if the base unit is not recognized).
+		 * 
+		 * @param unit
+		 *            the base unit for which the dimension is returned.
+		 * @return the dimension of the specified unit.
+		 */
+		Dimension getDimension(Unit<?> unit);
+
+		/**
+		 * Returns the normalization transform of the specified base unit (
+		 * {@link UnitConverter#IDENTITY IDENTITY} if the base unit is not
+		 * recognized).
+		 * 
+		 * @param unit
+		 *            the base unit for which the transform is returned.
+		 * @return the normalization transform.
+		 */
+		UnitConverter getTransform(Unit<?> unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/ProductUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/ProductUnit.java
new file mode 100644
index 0000000..d57a04a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/ProductUnit.java
@@ -0,0 +1,548 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Dimension;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.Measure;
+
+/**
+ * <p>  This class represents units formed by the product of rational powers of
+ *      existing units.</p>
+ *
+ * <p> This class maintains the canonical form of this product (simplest form
+ *     after factorization). For example: <code>METRE.pow(2).divide(METRE)</code>
+ *     returns <code>METRE</code>.</p>
+ *
+ * @param <Q> The type of the quantity measured by this unit.
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.3 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ * @see AbstractUnit#multiply(AbstractUnit)
+ * @see AbstractUnit#divide(AbstractUnit)
+ * @see AbstractUnit#pow(int)
+ * @see AbstractUnit#root(int)
+ */
+public final class ProductUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> implements Unit<Q> {
+
+    /**
+	 * For cross-version compatibility.
+	 */
+	private static final long serialVersionUID = -736056598162783537L;
+
+	/**
+     * Holds the units composing this product unit.
+     */
+    private final Element[] elements;
+
+    /**
+     * Holds the hashcode (optimization).
+     */
+    private int hashCode;
+
+    /**
+     * Default constructor (used solely to create <code>ONE</code> instance).
+     */
+    public ProductUnit() {
+        elements = new Element[0];
+    }
+
+    /**
+     * Copy constructor (allows for parameterization of product units).
+     *
+     * @param productUnit the product unit source.
+     * @throws ClassCastException if the specified unit is not a product unit.
+     */
+    public ProductUnit(Unit<?> productUnit) {
+        this.elements = ((ProductUnit<?>) productUnit).elements;
+    }
+
+    /**
+     * Product unit constructor.
+     *
+     * @param elements the product elements.
+     */
+    private ProductUnit(Element[] elements) {
+        this.elements = elements;
+    }
+
+    /**
+     * Returns the unit defined from the product of the specified elements.
+     *
+     * @param leftElems left multiplicand elements.
+     * @param rightElems right multiplicand elements.
+     * @return the corresponding unit.
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private static Unit<?> getInstance(Element[] leftElems,
+            Element[] rightElems) {
+
+        // Merges left elements with right elements.
+        Element[] result = new Element[leftElems.length + rightElems.length];
+        int resultIndex = 0;
+        for (int i = 0; i < leftElems.length; i++) {
+            Unit<?> unit = leftElems[i].unit;
+            int p1 = leftElems[i].pow;
+            int r1 = leftElems[i].root;
+            int p2 = 0;
+            int r2 = 1;
+            for (int j = 0; j < rightElems.length; j++) {
+                if (unit.equals(rightElems[j].unit)) {
+                    p2 = rightElems[j].pow;
+                    r2 = rightElems[j].root;
+                    break; // No duplicate.
+                }
+            }
+            int pow = (p1 * r2) + (p2 * r1);
+            int root = r1 * r2;
+            if (pow != 0) {
+                int gcd = gcd(Math.abs(pow), root);
+                result[resultIndex++] = new Element(unit, pow / gcd, root / gcd);
+            }
+        }
+
+        // Appends remaining right elements not merged.
+        for (int i = 0; i < rightElems.length; i++) {
+            AbstractUnit<?> unit = (AbstractUnit<?>) rightElems[i].unit;
+            boolean hasBeenMerged = false;
+            for (int j = 0; j < leftElems.length; j++) {
+                if (unit.equals(leftElems[j].unit)) {
+                    hasBeenMerged = true;
+                    break;
+                }
+            }
+            if (!hasBeenMerged)
+                result[resultIndex++] = rightElems[i];
+        }
+
+        // Returns or creates instance.
+        if (resultIndex == 0)
+            return (Unit<?>) AbstractUnit.ONE;
+        else if ((resultIndex == 1) && (result[0].pow == result[0].root))
+            return (Unit<? extends Measure>) result[0].unit;
+        else {
+            Element[] elems = new Element[resultIndex];
+            for (int i = 0; i < resultIndex; i++) {
+                elems[i] = result[i];
+            }
+            return new ProductUnit(elems);
+        }
+    }
+
+    /**
+     * Returns the product of the specified units.
+     *
+     * @param left the left unit operand.
+     * @param right the right unit operand.
+     * @return <code>left * right</code>
+     */
+    public static Unit<?> getProductInstance(Unit<?> left,
+            Unit<?> right) {
+        Element[] leftElems;
+        if (left instanceof ProductUnit<?>)
+            leftElems = ((ProductUnit<?>) left).elements;
+        else
+            leftElems = new Element[]{new Element(left, 1, 1)};
+        Element[] rightElems;
+        if (right instanceof ProductUnit<?>)
+            rightElems = ((ProductUnit<?>) right).elements;
+        else
+            rightElems = new Element[]{new Element(right, 1, 1)};
+        return getInstance(leftElems, rightElems);
+    }
+
+    /**
+     * Returns the quotient of the specified units.
+     *
+     * @param left the dividend unit operand.
+     * @param right the divisor unit operand.
+     * @return <code>dividend / divisor</code>
+     */
+    public static Unit<?> getQuotientInstance(Unit<?> left,
+            Unit<?> right) {
+        Element[] leftElems;
+        if (left instanceof ProductUnit<?>)
+            leftElems = ((ProductUnit<?>) left).elements;
+        else
+            leftElems = new Element[]{new Element(left, 1, 1)};
+        Element[] rightElems;
+        if (right instanceof ProductUnit<?>) {
+            Element[] elems = ((ProductUnit<?>) right).elements;
+            rightElems = new Element[elems.length];
+            for (int i = 0; i < elems.length; i++) {
+                rightElems[i] = new Element(elems[i].unit, -elems[i].pow,
+                        elems[i].root);
+            }
+        } else
+            rightElems = new Element[]{new Element(right, -1, 1)};
+        return (AbstractUnit<?>) getInstance(leftElems, rightElems);
+    }
+
+    /**
+     * Returns the product unit corresponding to the specified root of the
+     * specified unit.
+     *
+     * @param unit the unit.
+     * @param n the root's order (n &gt; 0).
+     * @return <code>unit^(1/nn)</code>
+     * @throws ArithmeticException if <code>n == 0</code>.
+     */
+    public static Unit<?> getRootInstance(Unit<?> unit, int n) {
+        Element[] unitElems;
+        if (unit instanceof ProductUnit<?>) {
+            Element[] elems = ((ProductUnit<?>) unit).elements;
+            unitElems = new Element[elems.length];
+            for (int i = 0; i < elems.length; i++) {
+                int gcd = gcd(Math.abs(elems[i].pow), elems[i].root * n);
+                unitElems[i] = new Element(elems[i].unit, elems[i].pow / gcd,
+                        elems[i].root * n / gcd);
+            }
+        } else
+            unitElems = new Element[]{new Element(unit, 1, n)};
+        return getInstance(unitElems, new Element[0]);
+    }
+
+    /**
+     * Returns the product unit corresponding to this unit raised to the
+     * specified exponent.
+     *
+     * @param unit the unit.
+     * @param nn the exponent (nn &gt; 0).
+     * @return <code>unit^n</code>
+     */
+    static Unit<?> getPowInstance(AbstractUnit<?> unit, int n) {
+        Element[] unitElems;
+        if (unit instanceof ProductUnit<?>) {
+            Element[] elems = ((ProductUnit<?>) unit).elements;
+            unitElems = new Element[elems.length];
+            for (int i = 0; i < elems.length; i++) {
+                int gcd = gcd(Math.abs(elems[i].pow * n), elems[i].root);
+                unitElems[i] = new Element(elems[i].unit, elems[i].pow * n / gcd, elems[i].root / gcd);
+            }
+        } else
+            unitElems = new Element[]{new Element(unit, n, 1)};
+        return getInstance(unitElems, new Element[0]);
+    }
+
+    /**
+     * Returns the number of unit elements in this product.
+     *
+     * @return the number of unit elements.
+     */
+    public int getUnitCount() {
+        return elements.length;
+    }
+
+    /**
+     * Returns the unit element at the specified position.
+     *
+     * @param index the index of the unit element to return.
+     * @return the unit element at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= getUnitCount())</code>.
+     */
+    @SuppressWarnings("unchecked")
+	public Unit<? extends Measure> getUnit(int index) {
+        return (Unit<? extends Measure>) elements[index].getUnit();
+    }
+
+    /**
+     * Returns the power exponent of the unit element at the specified position.
+     *
+     * @param index the index of the unit element.
+     * @return the unit power exponent at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= getUnitCount())</code>.
+     */
+    public int getUnitPow(int index) {
+        return elements[index].getPow();
+    }
+
+    /**
+     * Returns the root exponent of the unit element at the specified position.
+     *
+     * @param index the index of the unit element.
+     * @return the unit root exponent at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= getUnitCount())</code>.
+     */
+    public int getUnitRoot(int index) {
+        return elements[index].getRoot();
+    }
+
+    @Override
+    public Map<Unit<?>, Integer> getProductUnits() {
+        Map<Unit<?>, Integer> units = new HashMap<Unit<?>, Integer>();
+        for (int i = 0; i < getUnitCount(); i++) {
+            units.put(getUnit(i), getUnitPow(i));
+        }
+        return units;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof ProductUnit<?>))
+            return false;
+        // Two products are equals if they have the same elements
+        // regardless of the elements' order.
+        Element[] elems = ((ProductUnit<?>) that).elements;
+        if (elements.length != elems.length)
+            return false;
+        for (int i = 0; i < elements.length; i++) {
+            boolean unitFound = false;
+            Element e = elements[i];
+            for (int j = 0; j < elems.length; j++) {
+                if (e.unit.equals(elems[j].unit))
+                    if ((e.pow != elems[j].pow) || (e.root != elems[j].root))
+                        return false;
+                    else {
+                        unitFound = true;
+                        break;
+                    }
+            }
+            if (!unitFound)
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        if (this.hashCode != 0)
+            return this.hashCode;
+        int code = 0;
+        for (int i = 0; i < elements.length; i++) {
+            code += elements[i].unit.hashCode() * (elements[i].pow * 3 - elements[i].root * 2);
+        }
+        this.hashCode = code;
+        return code;
+    }
+
+    @Override
+    public final UnitConverter getConverterToMetric() {
+        if (hasOnlyUnscaledMetricUnits()) // Product of standard units is a standard unit itself.
+            return AbstractConverter.IDENTITY;
+        UnitConverter converter = AbstractConverter.IDENTITY;
+        for (int i = 0; i < elements.length; i++) {
+            Element e = elements[i];
+            @SuppressWarnings("rawtypes")
+			UnitConverter cvtr = ((AbstractUnit) e.unit).getConverterToMetric();
+            if (!(cvtr.isLinear()))
+                throw new UnsupportedOperationException(e.unit + " is non-linear, cannot convert");
+            if (e.root != 1)
+                throw new UnsupportedOperationException(e.unit + " holds a base unit with fractional exponent");
+            int pow = e.pow;
+            if (pow < 0) { // Negative power.
+                pow = -pow;
+                cvtr = cvtr.inverse();
+            }
+            for (int j = 0; j < pow; j++) {
+                converter = converter.concatenate(cvtr);
+            }
+        }
+        return converter;
+    }
+
+    /**
+     * Indicates if this product unit is a standard unit.
+     *
+     * @return <code>true</code> if all elements are standard units;
+     *         <code>false</code> otherwise.
+     */
+    private boolean hasOnlyUnscaledMetricUnits() {
+        for (int i = 0; i < elements.length; i++) {
+            AbstractUnit<?> u = (AbstractUnit<?>) elements[i].unit;
+            if (!u.isUnscaledMetric())
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Dimension getDimension() {
+        Dimension dimension = DimensionImpl.NONE;
+        for (int i = 0; i < this.getUnitCount(); i++) {
+            Unit<?> unit = this.getUnit(i);
+            Dimension d = unit.getDimension().pow(this.getUnitPow(i)).root(this.getUnitRoot(i));
+            dimension = dimension.multiply(d);
+        }
+        return dimension;
+    }
+
+    @Override
+    public UnitConverter getDimensionalTransform() {
+        UnitConverter converter = AbstractConverter.IDENTITY;
+        for (int i = 0; i < this.getUnitCount(); i++) {
+            AbstractUnit<?> unit = (AbstractUnit<?>) this.getUnit(i);
+            UnitConverter cvtr = unit.getDimensionalTransform();
+            if (!(cvtr.isLinear()))
+                throw new UnsupportedOperationException(cvtr.getClass() + " is non-linear, cannot convert product unit");
+            if (this.getUnitRoot(i) != 1)
+                throw new UnsupportedOperationException(this + " holds a unit with fractional exponent");
+            int pow = this.getUnitPow(i);
+            if (pow < 0) { // Negative power.
+                pow = -pow;
+                cvtr = cvtr.inverse();
+            }
+            for (int j = 0; j < pow; j++) {
+                converter = converter.concatenate(cvtr);
+            }
+        }
+        return converter;
+    }
+
+    /**
+     * Returns the greatest common divisor (Euclid's algorithm).
+     *
+     * @param m the first number.
+     * @param nn the second number.
+     * @return the greatest common divisor.
+     */
+    private static int gcd(int m, int n) {
+        if (n == 0)
+            return m;
+        else
+            return gcd(n, m % n);
+    }
+
+    /**
+     * Inner product element represents a rational power of a single unit.
+     */
+    private final static class Element implements Serializable {
+
+        /**
+         *
+         */
+        private static final long serialVersionUID = 1649532173171667701L;
+
+        /**
+         * Holds the single unit.
+         */
+        private final Unit<?> unit;
+
+        /**
+         * Holds the power exponent.
+         */
+        private final int pow;
+
+        /**
+         * Holds the root exponent.
+         */
+        private final int root;
+
+        /**
+         * Structural constructor.
+         *
+         * @param unit the unit.
+         * @param pow the power exponent.
+         * @param root the root exponent.
+         */
+        private Element(Unit<?> unit, int pow, int root) {
+            this.unit = unit;
+            this.pow = pow;
+            this.root = root;
+        }
+
+        /**
+         * Returns this element's unit.
+         *
+         * @return the single unit.
+         */
+        public Unit<?> getUnit() {
+            return unit;
+        }
+
+        /**
+         * Returns the power exponent. The power exponent can be negative but is
+         * always different from zero.
+         *
+         * @return the power exponent of the single unit.
+         */
+        public int getPow() {
+            return pow;
+        }
+
+        /**
+         * Returns the root exponent. The root exponent is always greater than
+         * zero.
+         *
+         * @return the root exponent of the single unit.
+         */
+        public int getRoot() {
+            return root;
+        }
+    }
+
+	@Override
+	public UnitConverter getConverterToAny(Unit<?> arg0) {
+        if (hasOnlyUnscaledMetricUnits()) // Product of standard units is a standard unit itself.
+            return AbstractConverter.IDENTITY;
+        UnitConverter converter = AbstractConverter.IDENTITY;
+        for (int i = 0; i < elements.length; i++) {
+            Element e = elements[i];
+            UnitConverter cvtr;
+			try {
+				cvtr = e.unit.getConverterToAny(this);
+			} catch (UnconvertibleException e1) {
+				throw e1;
+			} catch (IncommensurableException e1) {
+				throw new UnsupportedOperationException(e1);
+			}
+            if (!(cvtr.isLinear()))
+                throw new UnsupportedOperationException(e.unit + " is non-linear, cannot convert");
+            if (e.root != 1)
+                throw new UnsupportedOperationException(e.unit + " holds a base unit with fractional exponent");
+            int pow = e.pow;
+            if (pow < 0) { // Negative power.
+                pow = -pow;
+                cvtr = cvtr.inverse();
+            }
+            for (int j = 0; j < pow; j++) {
+                converter = converter.concatenate(cvtr);
+            }
+        }
+        return converter;
+	}
+
+    @SuppressWarnings("unchecked")
+	@Override
+    protected Unit<Q> toMetric() {
+        if (hasOnlyUnscaledMetricUnits())
+            return this;
+        Unit<?> systemUnit = AbstractUnit.ONE;
+        for (int i = 0; i < elements.length; i++) {
+            Unit<?> unit = elements[i].unit.getSystemUnit();
+            unit = unit.pow(elements[i].pow);
+            unit = unit.root(elements[i].root);
+            systemUnit = systemUnit.multiply(unit);
+        }
+        return (Unit<Q>) systemUnit;
+    }
+
+	@Override
+	public Unit<Q> getSystemUnit() {
+		return toMetric();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/TransformedUnit.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/TransformedUnit.java
new file mode 100644
index 0000000..e98bc18
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/TransformedUnit.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p>
+ * This class represents the units derived from other units using
+ * {@linkplain AbstractConverter converters}.
+ * </p>
+ * 
+ * <p>
+ * Examples of transformed units:[code] CELSIUS = KELVIN.add(273.15); FOOT =
+ * METRE.times(3048).divide(10000); MILLISECOND = MILLI(SECOND); [/code]
+ * </p>
+ * 
+ * <p>
+ * Transformed units have no label. But like any other units, they may have
+ * labels attached to them (see
+ * {@link org.eclipse.uomo.units.AbstractFormat.SymbolMap SymbolMap}
+ * </p>
+ * 
+ * <p>
+ * Instances of this class are created through the
+ * {@link AbstractUnit#transform} method.
+ * </p>
+ * 
+ * @param <Q>
+ *            The type of the quantity measured by this unit.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2 ($Revision: 212 $), $Date: 2013-03-10 $
+ */
+public final class TransformedUnit<Q extends Quantity<Q>> extends
+		AbstractUnit<Q> {
+
+	@Override
+	public UnitConverter getConverterToAny(Unit<?> that)
+			throws IncommensurableException, UnconvertibleException {
+		if (toParentUnit != null) {
+			return toParentUnit.inverse();
+		}
+		return super.getConverterToAny(that);
+	}
+
+	/**
+	 * For cross-version compatibility.
+	 */
+	private static final long serialVersionUID = -442449068482939939L;
+
+	/**
+	 * Holds the parent unit (not a transformed unit).
+	 */
+	private final Unit<Q> parentUnit;
+
+	/**
+	 * Holds the converter to the parent unit.
+	 */
+	private final AbstractConverter toParentUnit;
+
+	/**
+	 * Creates a transformed unit from the specified parent unit.
+	 * 
+	 * @param parentUnit
+	 *            the untransformed unit from which this unit is derived.
+	 * @param toParentUnit
+	 *            the converter to the parent units.
+	 * @throws IllegalArgumentException
+	 *             if <code>toParentUnit ==
+	 *         {@link AbstractConverter#IDENTITY UnitConverter.IDENTITY}</code>
+	 */
+	public TransformedUnit(Unit<Q> parentUnit, AbstractConverter toParentUnit) {
+		if (toParentUnit == AbstractConverter.IDENTITY)
+			throw new IllegalArgumentException("Identity not allowed");
+		this.parentUnit = parentUnit;
+		this.toParentUnit = toParentUnit;
+	}
+
+	/**
+	 * Returns the parent unit for this unit. The parent unit is the
+	 * untransformed unit from which this unit is derived.
+	 * 
+	 * @return the untransformed unit from which this unit is derived.
+	 */
+	public Unit<Q> getParentUnit() {
+		return parentUnit;
+	}
+
+	/**
+	 * Returns the converter to the parent unit.
+	 * 
+	 * @return the converter to the parent unit.
+	 */
+	public UnitConverter toParentUnit() {
+		return toParentUnit;
+	}
+
+	@Override
+	public boolean equals(Object that) {
+		if (this == that)
+			return true;
+		if (!(that instanceof TransformedUnit<?>))
+			return false;
+		TransformedUnit<?> thatUnit = (TransformedUnit<?>) that;
+		return this.parentUnit.equals(thatUnit.parentUnit)
+				&& (this.toParentUnit != null && this.toParentUnit
+						.equals(thatUnit.toParentUnit));
+	}
+
+	@Override
+	public int hashCode() {
+		return parentUnit.hashCode()
+				+ (toParentUnit != null ? toParentUnit.hashCode() : 0);
+	}
+
+	@Override
+	protected Unit<Q> toMetric() {
+		return parentUnit.getSystemUnit();
+	}
+
+	@Override
+	public UnitConverter getConverterToMetric() {
+		return ((AbstractUnit<Q>) parentUnit).getConverterToMetric()
+				.concatenate(toParentUnit);
+	}
+
+	@Override
+	public Unit<Q> getSystemUnit() {
+		return toMetric();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/AddConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/AddConverter.java
new file mode 100644
index 0000000..a4b100e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/AddConverter.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.converter;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+
+/**
+ * <p> This class represents a converter adding a constant offset
+ *     to numeric values (<code>double</code> based).</p>
+ *
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ *
+ * @version 1.2 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public final class AddConverter extends AbstractConverter {
+
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 8088797685241019815L;
+
+    /**
+     * Holds the offset.
+     */
+    private final double offset;
+
+    /**
+     * Creates an add converter with the specified offset.
+     *
+     * @param  offset the offset value.
+     * @throws IllegalArgumentException if offset is <code>0.0</code>
+     *         (would result in identity converter).
+     */
+    public AddConverter(double offset) {
+        if (offset == 0.0) {
+            throw new IllegalArgumentException("Would result in identity converter");
+        }
+        this.offset = offset;
+    }
+
+    /**
+     * Returns the offset value for this add converter.
+     *
+     * @return the offset value.
+     */
+    public double getOffset() {
+        return offset;
+    }
+
+    @Override
+    public UnitConverter concatenate(UnitConverter converter) {
+        if (converter instanceof AddConverter) {
+            double newOffset = offset + ((AddConverter) converter).offset;
+            return newOffset == 0.0 ? IDENTITY : new AddConverter(newOffset);
+        } else {
+            return super.concatenate((AbstractConverter)converter);
+        }
+    }
+
+    @Override
+    public AddConverter inverse() {
+        return new AddConverter(-offset);
+    }
+
+    @Override
+    public double convert(double value) {
+        return value + offset;
+    }
+
+    @Override
+    public BigDecimal convert(BigDecimal value, MathContext ctx) throws ArithmeticException {
+         return value.add(BigDecimal.valueOf(offset), ctx);
+    }
+
+	@Override
+	public Number convert(Number value) {
+		return BigDecimal.valueOf(value.doubleValue()).add(BigDecimal.valueOf(offset));
+	}
+
+    @Override
+    public final String toString() {
+        return "AddConverter(" + offset + ")";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof AddConverter)) {
+            return false;
+        }
+        AddConverter that = (AddConverter) obj;
+        return this.offset == that.offset;
+    }
+
+    @Override
+    public int hashCode() {
+        long bits = Double.doubleToLongBits(offset);
+        return (int) (bits ^ (bits >>> 32));
+    }
+
+    @Override
+    public boolean isLinear() {
+        return false;
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/ExpConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/ExpConverter.java
new file mode 100644
index 0000000..9236b94
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/ExpConverter.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.converter;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+
+/**
+ * <p>
+ * This class represents a exponential converter of limited precision. Such
+ * converter is typically used to create inverse of logarithmic unit.
+ * 
+ * <p>
+ * Instances of this class are immutable.
+ * </p>
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1 ($Revision: 132 $), $Date: 2010-08-10 07:04:41 +0100 (Di, 10 Aug 2010) $
+ */
+public final class ExpConverter extends AbstractConverter {
+
+	/** The serialVersionUID */
+	private static final long serialVersionUID = -1862583888012861945L;
+
+	/**
+	 * Holds the logarithmic base.
+	 */
+	private final double base;
+
+	/**
+	 * Holds the natural logarithm of the base.
+	 */
+	private final double logOfBase;
+
+	/**
+	 * Creates a logarithmic converter having the specified base.
+	 * 
+	 * @param base
+	 *            the logarithmic base (e.g. <code>Math.E</code> for the Natural
+	 *            Logarithm).
+	 */
+	public ExpConverter(double base) {
+		this.base = base;
+		this.logOfBase = Math.log(base);
+	}
+
+	/**
+	 * Returns the exponential base of this converter.
+	 * 
+	 * @return the exponential base (e.g. <code>Math.E</code> for the Natural
+	 *         Exponential).
+	 */
+	public double getBase() {
+		return base;
+	}
+
+	@Override
+	public AbstractConverter inverse() {
+		return new LogConverter(base);
+	}
+
+	@Override
+	public final String toString() {
+		return "ExpConverter(" + base + ")";
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (!(obj instanceof ExpConverter))
+			return false;
+		ExpConverter that = (ExpConverter) obj;
+		return this.base == that.base;
+	}
+
+	@Override
+	public int hashCode() {
+		long bits = Double.doubleToLongBits(base);
+		return (int) (bits ^ (bits >>> 32));
+	}
+
+	@Override
+	public double convert(double value) {
+		return Math.exp(logOfBase * value);
+	}
+
+	@Override
+	public BigDecimal convert(BigDecimal value, MathContext ctx)
+			throws ArithmeticException {
+		return BigDecimal.valueOf(convert(value.doubleValue())); // Reverts to
+																	// double
+																	// conversion.
+	}
+
+	@Override
+	public Number convert(Number value) {
+		if (value instanceof BigDecimal) {
+			return convert((BigDecimal) value, MathContext.DECIMAL128);
+		} else {
+			return convert(value.doubleValue());
+		}
+	}
+
+	@Override
+	public boolean isLinear() {
+		return false;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/LogConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/LogConverter.java
new file mode 100644
index 0000000..8f98e62
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/LogConverter.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.converter;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+
+/**
+ * <p> This class represents a logarithmic converter of limited precision.
+ *     Such converter  is typically used to create logarithmic unit.
+ *     For example:[code]
+ *     Unit<Dimensionless> BEL = Unit.ONE.transform(new LogConverter(10).inverse());
+ *     [/code]</p>
+ *
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4 ($Revision: 132 $), $Date: 2010-08-10 07:04:41 +0100 (Di, 10 Aug 2010) $
+ */
+public final class LogConverter extends AbstractConverter {
+
+    /** The serialVersionUID */
+    private static final long serialVersionUID = -5581266460675123322L;
+
+    /**
+     * Holds the logarithmic base.
+     */
+    private final double base;
+    /**
+     * Holds the natural logarithm of the base.
+     */
+    private final double logOfBase;
+
+    /**
+     * Creates a logarithmic converter having the specified base.
+     *
+     * @param  base the logarithmic base (e.g. <code>Math.E</code> for
+     *         the Natural Logarithm).
+     */
+    public LogConverter(double base) {
+        this.base = base;
+        logOfBase = Math.log(base);
+    }
+
+    /**
+     * Returns the logarithmic base of this converter.
+     *
+     * @return the logarithmic base (e.g. <code>Math.E</code> for
+     *         the Natural Logarithm).
+     */
+    public double getBase() {
+        return base;
+    }
+
+    @Override
+    public AbstractConverter inverse() {
+        return new ExpConverter(base);
+    }
+
+    @Override
+    public final String toString() {
+        return "LogConverter("+ base + ")";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof LogConverter))
+            return false;
+        LogConverter that = (LogConverter) obj;
+        return this.base == that.base;
+    }
+
+    @Override
+    public int hashCode() {
+        long bits = Double.doubleToLongBits(base);
+        return (int) (bits ^ (bits >>> 32));
+    }
+
+    @Override
+    public double convert(double amount) {
+        return Math.log(amount) / logOfBase;
+    }
+
+    @Override
+    public BigDecimal convert(BigDecimal value, MathContext ctx) throws ArithmeticException {
+        return BigDecimal.valueOf(convert(value.doubleValue())); // Reverts to double conversion.
+    }
+    
+	@Override
+	public Number convert(Number value) {
+		if (value instanceof BigDecimal) {
+			return convert((BigDecimal) value, MathContext.DECIMAL128);
+		} else {
+			return convert(value.doubleValue());
+		}
+	}
+
+    @Override
+    public boolean isLinear() {
+        return false;
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/MultiplyConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/MultiplyConverter.java
new file mode 100644
index 0000000..7f845e5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/MultiplyConverter.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.converter;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This class represents a converter multiplying numeric values by a
+ *     constant scaling factor (<code>double</code> based).</p>
+ *
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.5.1 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public final class MultiplyConverter extends AbstractConverter {
+    /** The serialVersionUID */
+    private static final long serialVersionUID = 6497743504427978825L;
+
+    /**
+     * Holds the scale factor.
+     */
+    private final double factor;
+
+    /**
+     * Creates a multiply converter with the specified scale factor.
+     *
+     * @param  factor the scaling factor.
+     * @throws IllegalArgumentException if coefficient is <code>1.0</code>
+     *        (would result in identity converter)
+     */
+    public MultiplyConverter(double factor) {
+        if (factor == 1.0)
+            throw new IllegalArgumentException("Would result in identity converter");
+        this.factor = factor;
+    }
+
+    /**
+     * Returns the scale factor of this converter.
+     *
+     * @return the scale factor.
+     */
+    public double getFactor() {
+        return factor;
+    }
+
+    @Override
+    public UnitConverter inverse() {
+        return new MultiplyConverter(1.0 / factor);
+    }
+
+    @Override
+    public double convert(double value) {
+        return value * factor;
+    }
+
+    @Override
+    public BigDecimal convert(BigDecimal value, MathContext ctx) throws ArithmeticException {
+          return value.multiply(BigDecimal.valueOf(factor), ctx);
+    }
+    
+	@Override
+	public Number convert(Number value) {
+		if (value instanceof BigDecimal) {
+			return convert((BigDecimal) value, MathContext.DECIMAL128);
+		} else {
+			return convert(value.doubleValue());
+		}
+	}
+
+    @Override
+    public final String toString() {
+        return "MultiplyConverter("+ factor + ")";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof MultiplyConverter))
+            return false;
+        MultiplyConverter that = (MultiplyConverter) obj;
+        return this.factor == that.factor;
+    }
+
+    @Override
+    public int hashCode() {
+        long bits = Double.doubleToLongBits(factor);
+    return (int)(bits ^ (bits >>> 32));
+    }
+
+    @Override
+    public boolean isLinear() {
+        return true;
+    }
+
+	@Override
+	public UnitConverter concatenate(UnitConverter converter) {
+      if (converter instanceof MultiplyConverter) {
+	      double newfactor = factor * ((MultiplyConverter) converter).factor;
+	      return newfactor == 1.0 ? IDENTITY : new MultiplyConverter(newfactor);
+      } else
+    	  return super.concatenate(converter);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/RationalConverter.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/RationalConverter.java
new file mode 100644
index 0000000..919612a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/converter/RationalConverter.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * <p> This class represents a converter multiplying numeric values by an
+ *     exact scaling factor (represented as the quotient of two
+ *     <code>BigInteger</code> numbers).</p>
+ *
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public final class RationalConverter extends AbstractConverter {
+
+    /** The serialVersionUID */
+    private static final long serialVersionUID = 5313011404391445406L;
+
+    /**
+     * Holds the converter dividend.
+     */
+    private final BigInteger dividend;
+    /**
+     * Holds the converter divisor (always positive).
+     */
+    private final BigInteger divisor;
+
+    /**
+     * Creates a rational converter with the specified dividend and
+     * divisor.
+     *
+     * @param dividend the dividend.
+     * @param divisor the positive divisor.
+     * @throws IllegalArgumentException if <code>divisor &lt;= 0</code>
+     * @throws IllegalArgumentException if <code>dividend == divisor</code>
+     */
+    public RationalConverter(BigInteger dividend, BigInteger divisor) {
+          if (divisor.compareTo(BigInteger.ZERO) <= 0)
+            throw new IllegalArgumentException("Negative or zero divisor");
+        if (dividend.equals(divisor))
+            throw new IllegalArgumentException("Would result in identity converter");
+        this.dividend = dividend; // Exact conversion.
+        this.divisor = divisor; // Exact conversion.
+    }
+    
+    /**
+     * Creates a rational converter with the specified dividend and
+     * divisor.
+     *
+     * @param dividend the dividend.
+     * @param divisor the positive divisor.
+     * @throws IllegalArgumentException if <code>divisor &lt;= 0</code>
+     * @throws IllegalArgumentException if <code>dividend == divisor</code>
+     */
+    public RationalConverter(long dividend, long divisor) {
+    	this(BigInteger.valueOf(dividend), BigInteger.valueOf(divisor));
+    }
+
+    /**
+     * Returns the integer dividend for this rational converter.
+     *
+     * @return this converter dividend.
+     */
+    public BigInteger getDividend() {
+        return dividend;
+    }
+
+    /**
+     * Returns the integer (positive) divisor for this rational converter.
+     *
+     * @return this converter divisor.
+     */
+    public BigInteger getDivisor() {
+        return divisor;
+    }
+
+    @Override
+    public double convert(double value) {
+        return value * toDouble(dividend) / toDouble(divisor);
+    }
+
+    // Optimization of BigInteger.doubleValue() (implementation too inneficient).
+    private static double toDouble(BigInteger integer) {
+        return (integer.bitLength() < 64) ? integer.longValue() : integer.doubleValue();
+    }
+
+    @Override
+    public BigDecimal convert(BigDecimal value, MathContext ctx) throws ArithmeticException {
+        BigDecimal decimalDividend = new BigDecimal(dividend, 0);
+        BigDecimal decimalDivisor = new BigDecimal(divisor, 0);
+        return value.multiply(decimalDividend, ctx).divide(decimalDivisor, ctx);
+    }
+
+	@Override
+	public Number convert(Number value) {
+		if (value instanceof BigDecimal) {
+			return convert((BigDecimal) value, MathContext.DECIMAL128);
+		} else {
+			return convert(value.doubleValue());
+		}
+	}
+	
+    @Override
+    public UnitConverter concatenate(UnitConverter converter) {
+        if (converter instanceof RationalConverter) {
+            RationalConverter that = (RationalConverter) converter;
+            BigInteger newDividend = this.getDividend().multiply(that.getDividend());
+            BigInteger newDivisor = this.getDivisor().multiply(that.getDivisor());
+            BigInteger gcd = newDividend.gcd(newDivisor);
+            newDividend = newDividend.divide(gcd);
+            newDivisor = newDivisor.divide(gcd);
+            return (newDividend.equals(BigInteger.ONE) && newDivisor.equals(BigInteger.ONE))
+                    ? IDENTITY : new RationalConverter(newDividend, newDivisor);
+        } else
+            return super.concatenate(converter);
+    }
+
+    @Override
+    public RationalConverter inverse() {
+        return dividend.signum() == -1 ? new RationalConverter(getDivisor().negate(), getDividend().negate())
+                : new RationalConverter(getDivisor(), getDividend());
+    }
+
+    @Override
+    public final String toString() {
+        return "RationalConverter("+ dividend +  "," + divisor + ")";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof RationalConverter))
+            return false;
+        RationalConverter that = (RationalConverter) obj;
+        return this.dividend.equals(that.dividend) &&
+                this.divisor.equals(that.divisor);
+    }
+
+    @Override
+    public int hashCode() {
+        return dividend.hashCode() + divisor.hashCode();
+    }
+
+    @Override
+    public boolean isLinear() {
+        return true;
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/LocalUnitFormatImpl.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/LocalUnitFormatImpl.java
new file mode 100644
index 0000000..6138120
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/LocalUnitFormatImpl.java
@@ -0,0 +1,721 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Eric Russell - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.format;
+
+import static org.eclipse.uomo.units.SI.CUBIC_METRE;
+import static org.eclipse.uomo.units.SI.GRAM;
+import static org.eclipse.uomo.units.SI.KILOGRAM;
+import static org.eclipse.uomo.units.impl.system.USCustomary.LITER;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigInteger;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Formattable;
+import java.util.Formatter;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractConverter.Compound;
+import org.eclipse.uomo.units.AbstractFormat;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.SymbolMap;
+import org.eclipse.uomo.units.impl.AnnotatedUnit;
+import org.eclipse.uomo.units.impl.BaseUnit;
+import org.eclipse.uomo.units.impl.TransformedUnit;
+import org.eclipse.uomo.units.impl.converter.AddConverter;
+import org.eclipse.uomo.units.impl.converter.ExpConverter;
+import org.eclipse.uomo.units.impl.converter.LogConverter;
+import org.eclipse.uomo.units.impl.converter.MultiplyConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.eclipse.uomo.units.Messages;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+import com.ibm.icu.util.ULocale;
+
+/**
+ * <p>
+ * This class represents the local sensitive format.
+ * </p>
+ * 
+ * <h3>Here is the grammar for Units in Extended Backus-Naur Form (EBNF)</h3>
+ * <p>
+ * Note that the grammar has been left-factored to be suitable for use by a
+ * top-down parser generator such as <a
+ * href="https://javacc.dev.java.net/">JavaCC</a>
+ * </p>
+ * <table width="90%" align="center">
+ * <tr>
+ * <th colspan="3" align="left">Lexical Entities:</th>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;sign&gt;</td>
+ * <td>:=</td>
+ * <td>"+" | "-"</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;digit&gt;</td>
+ * <td>:=</td>
+ * <td>"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;superscript_digit&gt;</td>
+ * <td>:=</td>
+ * <td>"⁰" | "¹" | "²" | "³" | "⁴" | "⁵" | "⁶" | "⁷" | "⁸" | "⁹"</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;integer&gt;</td>
+ * <td>:=</td>
+ * <td>(&lt;digit&gt;)+</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;number&gt;</td>
+ * <td>:=</td>
+ * <td>(&lt;sign&gt;)? (&lt;digit&gt;)* (".")? (&lt;digit&gt;)+ (("e" | "E")
+ * (&lt;sign&gt;)? (&lt;digit&gt;)+)?</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;exponent&gt;</td>
+ * <td>:=</td>
+ * <td>( "^" ( &lt;sign&gt; )? &lt;integer&gt; ) <br>
+ * | ( "^(" (&lt;sign&gt;)? &lt;integer&gt; ( "/" (&lt;sign&gt;)?
+ * &lt;integer&gt; )? ")" ) <br>
+ * | ( &lt;superscript_digit&gt; )+</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;initial_char&gt;</td>
+ * <td>:=</td>
+ * <td>? Any Unicode character excluding the following: ASCII control &
+ * whitespace (&#92;u0000 - &#92;u0020), decimal digits '0'-'9', '('
+ * (&#92;u0028), ')' (&#92;u0029), '*' (&#92;u002A), '+' (&#92;u002B), '-'
+ * (&#92;u002D), '.' (&#92;u002E), '/' (&#92;u005C), ':' (&#92;u003A), '^'
+ * (&#92;u005E), '²' (&#92;u00B2), '³' (&#92;u00B3), '·' (&#92;u00B7), '¹'
+ * (&#92;u00B9), '⁰' (&#92;u2070), '⁴' (&#92;u2074), '⁵' (&#92;u2075), '⁶'
+ * (&#92;u2076), '⁷' (&#92;u2077), '⁸' (&#92;u2078), '⁹' (&#92;u2079) ?</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;unit_identifier&gt;</td>
+ * <td>:=</td>
+ * <td>&lt;initial_char&gt; ( &lt;initial_char&gt; | &lt;digit&gt; )*</td>
+ * </tr>
+ * <tr>
+ * <th colspan="3" align="left">Non-Terminals:</th>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;unit_expr&gt;</td>
+ * <td>:=</td>
+ * <td>&lt;compound_expr&gt;</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;compound_expr&gt;</td>
+ * <td>:=</td>
+ * <td>&lt;add_expr&gt; ( ":" &lt;add_expr&gt; )*</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;add_expr&gt;</td>
+ * <td>:=</td>
+ * <td>( &lt;number&gt; &lt;sign&gt; )? &lt;mul_expr&gt; ( &lt;sign&gt;
+ * &lt;number&gt; )?</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;mul_expr&gt;</td>
+ * <td>:=</td>
+ * <td>&lt;exponent_expr&gt; ( ( ( "*" | "·" ) &lt;exponent_expr&gt; ) | ( "/"
+ * &lt;exponent_expr&gt; ) )*</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;exponent_expr&gt;</td>
+ * <td>:=</td>
+ * <td>( &lt;atomic_expr&gt; ( &lt;exponent&gt; )? ) <br>
+ * | (&lt;integer&gt; "^" &lt;atomic_expr&gt;) <br>
+ * | ( ( "log" ( &lt;integer&gt; )? ) | "ln" ) "(" &lt;add_expr&gt; ")" )</td>
+ * </tr>
+ * <tr valign="top">
+ * <td>&lt;atomic_expr&gt;</td>
+ * <td>:=</td>
+ * <td>&lt;number&gt; <br>
+ * | &lt;unit_identifier&gt; <br>
+ * | ( "(" &lt;add_expr&gt; ")" )</td>
+ * </tr>
+ * </table>
+ * 
+ * @author <a href="mailto:eric-r@northwestern.edu">Eric Russell</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4.1 ($Revision: 232 $), $Date: 2010-10-13 17:13:18 +0200 (Mi, 13 Okt 2010) $
+ */
+public class LocalUnitFormatImpl extends AbstractFormat {
+
+	// ////////////////////////////////////////////////////
+	// Class variables //
+	// ////////////////////////////////////////////////////
+	/**
+	 * serialVersionUID
+	 */
+	private static final long serialVersionUID = -2046025264383639924L;
+
+	/**
+	 * Name of the resource bundle
+	 */
+	private static final String BUNDLE_NAME = LocalUnitFormatImpl.class.getPackage()
+			.getName() + ".messages"; //$NON-NLS-1$
+
+	/**
+	 * Default locale instance. If the default locale is changed after the class
+	 * is initialized, this instance will no longer be used.
+	 */
+	private static final LocalUnitFormatImpl DEFAULT_INSTANCE = new LocalUnitFormatImpl(
+			new SymbolMapImpl(ResourceBundle.getBundle(BUNDLE_NAME)), Locale.getDefault());
+
+	/** Multiplicand character */
+	private static final char MIDDLE_DOT = '\u00b7'; //$NON-NLS-1$
+	
+	/** Exponent 1 character */
+	private static final char EXPONENT_1 = '\u00b9'; //$NON-NLS-1$
+	
+	/** Exponent 2 character */
+	private static final char EXPONENT_2 = '\u00b2'; //$NON-NLS-1$
+	
+	/** Operator precedence for the addition and subtraction operations */
+	private static final int ADDITION_PRECEDENCE = 0;
+
+	/** Operator precedence for the multiplication and division operations */
+	private static final int PRODUCT_PRECEDENCE = ADDITION_PRECEDENCE + 2;
+
+	/** Operator precedence for the exponentiation and logarithm operations */
+	private static final int EXPONENT_PRECEDENCE = PRODUCT_PRECEDENCE + 2;
+
+
+	
+	/**
+	 * Operator precedence for a unit identifier containing no mathematical
+	 * operations (i.e., consisting exclusively of an identifier and possibly a
+	 * prefix). Defined to be <code>Integer.MAX_VALUE</code> so that no operator
+	 * can have a higher precedence.
+	 */
+	private static final int NOOP_PRECEDENCE = Integer.MAX_VALUE;
+
+	private final ULocale uLocale;
+	
+	// /////////////////
+	// Class methods //
+	// /////////////////
+	/**
+	 * Returns the instance for the current default locale (non-ascii characters
+	 * are allowed)
+	 */
+	public static LocalUnitFormatImpl getInstance() {
+		return DEFAULT_INSTANCE;
+	}
+
+	/**
+	 * Returns an instance for the given locale.
+	 * 
+	 * @param locale
+	 */
+	public static LocalUnitFormatImpl getInstance(Locale locale) {
+		return new LocalUnitFormatImpl(new SymbolMapImpl(ResourceBundle.getBundle(
+				BUNDLE_NAME, locale)), locale);
+	}
+
+	/** Returns an instance for the given symbol map. */
+	protected static LocalUnitFormatImpl getInstance(SymbolMapImpl symbols, Locale locale) {
+		return new LocalUnitFormatImpl(symbols, locale);
+	}
+
+	// //////////////////////
+	// Instance variables //
+	// //////////////////////
+	/**
+	 * The symbol map used by this instance to map between
+	 * {@link org.unitsofmeasure.Unit Unit}s and <code>String</code>s, etc...
+	 */
+	private transient SymbolMapImpl symbolMap;
+
+	// ////////////////
+	// Constructors //
+	// ////////////////
+	/**
+	 * Base constructor.
+	 * 
+	 */
+	public LocalUnitFormatImpl() {
+		this(new SymbolMapImpl(ResourceBundle.getBundle(
+				BUNDLE_NAME, Locale.getDefault())), Locale.getDefault());
+	}
+	
+	/**
+	 * Private constructor.
+	 * 
+	 * @param symbols
+	 *            the symbol mapping.
+	 */
+	private LocalUnitFormatImpl(SymbolMapImpl symbols, Locale loc) {
+		symbolMap = symbols;
+		uLocale = ULocale.forLocale(loc);
+	}
+
+	// //////////////////////
+	// Instance methods //
+	// //////////////////////
+	/**
+	 * Get the symbol map used by this instance to map between
+	 * {@link org.unitsofmeasure.Unit Unit}s and <code>String</code>s, etc...
+	 * 
+	 * @return SymbolMap the current symbol map
+	 */
+	public SymbolMap getSymbolMap() {
+		return symbolMap;
+	}
+
+	// //////////////
+	// Formatting //
+	// //////////////
+	public Appendable format(Unit<?> unit, Appendable appendable)
+			throws IOException {
+		formatInternal(unit, appendable);
+		if (unit instanceof AnnotatedUnit<?>) {
+			AnnotatedUnit<?> annotatedUnit = (AnnotatedUnit<?>) unit;
+			if (annotatedUnit.getAnnotation() != null) {
+				appendable.append('{');
+				appendable.append(annotatedUnit.getAnnotation());
+				appendable.append('}');
+			}
+		}
+		return appendable;
+	}
+
+	public Unit<?> parse(CharSequence csq, ParsePosition cursor)
+			throws IllegalArgumentException {
+		// Parsing reads the whole character sequence from the parse position.
+		int start = cursor != null ? cursor.getIndex() : 0;
+		int end = csq.length();
+		if (end <= start) {
+			return AbstractUnit.ONE;
+		}
+		String source = csq.subSequence(start, end).toString().trim();
+		if (source.length() == 0) {
+			return AbstractUnit.ONE;
+		}
+		try {
+			UnitParser parser = new UnitParser(symbolMap, new StringReader(
+					source));
+			Unit<?> result = parser.parseUnit();
+			if (cursor != null)
+				cursor.setIndex(end);
+			return result;
+		} catch (ParseException e) {
+			if (cursor != null) {
+				if (e.currentToken != null) {
+					cursor.setErrorIndex(start + e.currentToken.endColumn);
+				} else {
+					cursor.setErrorIndex(start);
+				}
+			}
+			throw new IllegalArgumentException(e.getMessage());
+		} catch (TokenMgrError e) {
+			cursor.setErrorIndex(start);
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	/**
+	 * Format the given unit to the given StringBuffer, then return the operator
+	 * precedence of the outermost operator in the unit expression that was
+	 * formatted. See {@link ConverterFormat} for the constants that define the
+	 * various precedence values.
+	 * 
+	 * @param unit
+	 *            the unit to be formatted
+	 * @param buffer
+	 *            the <code>StringBuffer</code> to be written to
+	 * @return the operator precedence of the outermost operator in the unit
+	 *         expression that was output
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private int formatInternal(Unit<?> unit, Appendable buffer)
+			throws IOException {
+		if (unit instanceof AnnotatedUnit<?>) {
+			unit = ((AnnotatedUnit<?>) unit).getActualUnit();
+			// } else if (unit instanceof ProductUnit<?>) {
+			// ProductUnit<?> p = (ProductUnit<?>)unit;
+		}
+		String symbol = symbolMap.getSymbol(unit);
+		if (symbol != null) {
+			buffer.append(symbol);
+			return NOOP_PRECEDENCE;
+		} else if (unit.getProductUnits() != null) {
+			Map<Unit<?>, Integer> productUnits = (Map<Unit<?>, Integer>) unit.getProductUnits();
+			int negativeExponentCount = 0;
+			// Write positive exponents first...
+			boolean start = true;
+			for (Map.Entry<Unit<?>, Integer> e : productUnits.entrySet()) {
+				int pow = e.getValue();
+				if (pow >= 0) {
+					formatExponent(e.getKey(), pow, 1, !start, buffer);
+					start = false;
+				} else {
+					negativeExponentCount += 1;
+				}
+			}
+			// ..then write negative exponents.
+			if (negativeExponentCount > 0) {
+				if (start) {
+					buffer.append('1');
+				}
+				buffer.append('/');
+				if (negativeExponentCount > 1) {
+					buffer.append('(');
+				}
+				start = true;
+				for (Map.Entry<Unit<?>, Integer> e : productUnits.entrySet()) {
+					int pow = e.getValue();
+					if (pow < 0) {
+						formatExponent(e.getKey(), -pow, 1, !start, buffer);
+						start = false;
+					}
+				}
+				if (negativeExponentCount > 1) {
+					buffer.append(')');
+				}
+			}
+			return PRODUCT_PRECEDENCE;
+		} else if (unit instanceof BaseUnit<?>) {
+			buffer.append(((BaseUnit<?>) unit).getSymbol());
+			return NOOP_PRECEDENCE;
+		} else if (unit.getSymbol() != null) { // Alternate unit.
+			buffer.append(unit.getSymbol());
+			return NOOP_PRECEDENCE;
+		} else { // A transformed unit or new unit type!
+			UnitConverter converter = null;
+			boolean printSeparator = false;
+			StringBuilder temp = new StringBuilder();
+			int unitPrecedence = NOOP_PRECEDENCE;
+			Unit<?> parentUnit = unit.getSystemUnit();
+			converter = ((AbstractUnit<?>) unit).getConverterToMetric();
+			if (KILOGRAM.equals(parentUnit)) {
+				// More special-case hackery to work around gram/kilogram
+				// incosistency
+				if (unit.equals(GRAM)) {
+					buffer.append(symbolMap.getSymbol(GRAM));
+					return NOOP_PRECEDENCE;
+				}
+				parentUnit = GRAM;
+				if (unit instanceof TransformedUnit<?>) {
+					converter = ((TransformedUnit<?>) unit).toParentUnit();
+				} else {
+					converter = unit.getConverterTo((Unit) GRAM);
+				}
+			} else if (CUBIC_METRE.equals(parentUnit)) {
+				if (converter != null) {
+					parentUnit = LITER;
+				}
+			}
+
+			if (unit instanceof TransformedUnit) {
+				TransformedUnit transUnit = (TransformedUnit) unit;
+				if (parentUnit== null) parentUnit = transUnit.getParentUnit();
+//				String x = parentUnit.toString();
+				converter = transUnit.toParentUnit();
+			}
+
+			unitPrecedence = formatInternal(parentUnit, temp);
+			printSeparator = !parentUnit.equals(AbstractUnit.ONE);
+			int result = formatConverter(converter, printSeparator,
+					unitPrecedence, temp);
+			buffer.append(temp);
+			return result;
+		}
+	}
+
+	/**
+	 * Format the given unit raised to the given fractional power to the given
+	 * <code>StringBuffer</code>.
+	 * 
+	 * @param unit
+	 *            Unit the unit to be formatted
+	 * @param pow
+	 *            int the numerator of the fractional power
+	 * @param root
+	 *            int the denominator of the fractional power
+	 * @param continued
+	 *            boolean <code>true</code> if the converter expression should
+	 *            begin with an operator, otherwise <code>false</code>. This
+	 *            will always be true unless the unit being modified is equal to
+	 *            Unit.ONE.
+	 * @param buffer
+	 *            StringBuffer the buffer to append to. No assumptions should be
+	 *            made about its content.
+	 */
+	private void formatExponent(Unit<?> unit, int pow, int root,
+			boolean continued, Appendable buffer) throws IOException {
+		if (continued) {
+			buffer.append(MIDDLE_DOT);
+		}
+		StringBuilder temp = new StringBuilder();
+		int unitPrecedence = formatInternal(unit, temp);
+
+		if (unitPrecedence < PRODUCT_PRECEDENCE) {
+			temp.insert(0, '('); //$NON-NLS-1$
+			temp.append(')'); //$NON-NLS-1$
+		}
+		buffer.append(temp);
+		if ((root == 1) && (pow == 1)) {
+			// do nothing
+		} else if ((root == 1) && (pow > 1)) {
+			String powStr = Integer.toString(pow);
+			for (int i = 0; i < powStr.length(); i += 1) {
+				char c = powStr.charAt(i);
+				switch (c) {
+				case '0':
+					buffer.append('\u2070'); //$NON-NLS-1$
+					break;
+				case '1':
+					buffer.append(EXPONENT_1); //$NON-NLS-1$
+					break;
+				case '2':
+					buffer.append(EXPONENT_2);
+					break;
+				case '3':
+					buffer.append('\u00b3'); //$NON-NLS-1$
+					break;
+				case '4':
+					buffer.append('\u2074'); //$NON-NLS-1$
+					break;
+				case '5':
+					buffer.append('\u2075'); //$NON-NLS-1$
+					break;
+				case '6':
+					buffer.append('\u2076'); //$NON-NLS-1$
+					break;
+				case '7':
+					buffer.append('\u2077'); //$NON-NLS-1$
+					break;
+				case '8':
+					buffer.append('\u2078'); //$NON-NLS-1$
+					break;
+				case '9':
+					buffer.append('\u2079'); //$NON-NLS-1$
+					break;
+				}
+			}
+		} else if (root == 1) {
+			buffer.append('^'); //$NON-NLS-1$
+			buffer.append(String.valueOf(pow));
+		} else {
+			buffer.append("^("); //$NON-NLS-1$
+			buffer.append(String.valueOf(pow));
+			buffer.append('/'); //$NON-NLS-1$
+			buffer.append(String.valueOf(root));
+			buffer.append(')'); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Formats the given converter to the given StringBuilder and returns the
+	 * operator precedence of the converter's mathematical operation. This is
+	 * the default implementation, which supports all built-in UnitConverter
+	 * implementations. Note that it recursively calls itself in the case of a
+	 * {@link org.eclipse.uomo.units.internal.AbstractConverter.converter.UnitConverter.Compound
+	 * Compound} converter.
+	 * 
+	 * @param converter
+	 *            the converter to be formatted
+	 * @param continued
+	 *            <code>true</code> if the converter expression should begin
+	 *            with an operator, otherwise <code>false</code>.
+	 * @param unitPrecedence
+	 *            the operator precedence of the operation expressed by the unit
+	 *            being modified by the given converter.
+	 * @param buffer
+	 *            the <code>StringBuffer</code> to append to.
+	 * @return the operator precedence of the given UnitConverter
+	 */
+	private int formatConverter(UnitConverter converter, boolean continued,
+			int unitPrecedence, StringBuilder buffer) {
+		ParsePrefix prefix = symbolMap
+				.getPrefixObject((AbstractConverter) converter);
+		if ((prefix != null) && (unitPrecedence == NOOP_PRECEDENCE)) {
+			buffer.insert(0, symbolMap.getSymbol(prefix));
+			return NOOP_PRECEDENCE;
+		} else if (converter instanceof AddConverter) {
+			if (unitPrecedence < ADDITION_PRECEDENCE) {
+				buffer.insert(0, '(');
+				buffer.append(')');
+			}
+			double offset = ((AddConverter) converter).getOffset();
+			if (offset < 0) {
+				buffer.append("-"); //$NON-NLS-1$
+				offset = -offset;
+			} else if (continued) {
+				buffer.append("+"); //$NON-NLS-1$
+			}
+			long lOffset = (long) offset;
+			if (lOffset == offset) {
+				buffer.append(lOffset);
+			} else {
+				buffer.append(offset);
+			}
+			return ADDITION_PRECEDENCE;
+		} else if (converter instanceof LogConverter) {
+			double base = ((LogConverter) converter).getBase();
+			StringBuffer expr = new StringBuffer();
+			if (base == StrictMath.E) {
+				expr.append("ln"); //$NON-NLS-1$
+			} else {
+				expr.append("log"); //$NON-NLS-1$
+				if (base != 10) {
+					expr.append((int) base);
+				}
+			}
+			expr.append("("); //$NON-NLS-1$
+			buffer.insert(0, expr);
+			buffer.append(")"); //$NON-NLS-1$
+			return EXPONENT_PRECEDENCE;
+		} else if (converter instanceof ExpConverter) {
+			if (unitPrecedence < EXPONENT_PRECEDENCE) {
+				buffer.insert(0, '(');
+				buffer.append(')');
+			}
+			StringBuffer expr = new StringBuffer();
+			double base = ((ExpConverter) converter).getBase();
+			if (base == StrictMath.E) {
+				expr.append('e');
+			} else {
+				expr.append((int) base);
+			}
+			expr.append('^'); 
+			buffer.insert(0, expr);
+			return EXPONENT_PRECEDENCE;
+		} else if (converter instanceof MultiplyConverter) {
+			if (unitPrecedence < PRODUCT_PRECEDENCE) {
+				buffer.insert(0, '(');
+				buffer.append(')');
+			}
+			if (continued) {
+				buffer.append(MIDDLE_DOT);
+			}
+			double factor = ((MultiplyConverter) converter).getFactor();
+			long lFactor = (long) factor;
+			if (lFactor == factor) {
+				buffer.append(lFactor);
+			} else {
+				buffer.append(factor);
+			}
+			return PRODUCT_PRECEDENCE;
+		} else if (converter instanceof RationalConverter) {
+			if (unitPrecedence < PRODUCT_PRECEDENCE) {
+				buffer.insert(0, '(');
+				buffer.append(')');
+			}
+			RationalConverter rationalConverter = (RationalConverter) converter;
+			if (!rationalConverter.getDividend().equals(BigInteger.ONE)) {
+				if (continued) {
+					buffer.append(MIDDLE_DOT);
+				}
+				buffer.append(rationalConverter.getDividend());
+			}
+			if (!rationalConverter.getDivisor().equals(BigInteger.ONE)) {
+				buffer.append('/');
+				buffer.append(rationalConverter.getDivisor());
+			}
+			return PRODUCT_PRECEDENCE;
+		} else if (converter instanceof AbstractConverter.Compound) {
+			AbstractConverter.Compound compound = (Compound) converter;
+			if (compound.getLeft() == AbstractConverter.IDENTITY) {
+				return formatConverter(compound.getRight(), true,
+						unitPrecedence, buffer);
+			} else {				
+		    	if (compound.getLeft() instanceof Formattable) {
+		    		return formatFormattable((Formattable)compound.getLeft(), unitPrecedence, buffer);
+		    	} else if (compound.getRight() instanceof Formattable) {
+		    		return formatFormattable((Formattable)compound.getRight(), unitPrecedence, buffer);	    	
+				} else {
+					return formatConverter(compound.getLeft(), true,
+							unitPrecedence, buffer);
+					// FIXME use getRight() here, too
+				}
+			}
+				// return formatConverter(compound.getRight(), true,
+			// unitPrecedence, buffer);
+			
+		} else {
+			if (converter != null) {
+//				throw new IllegalArgumentException(
+//						"Unable to format the given UnitConverter: " + converter.getClass()); //$NON-NLS-1$
+				buffer.replace(0, 1, converter.toString());
+				return NOOP_PRECEDENCE;
+			} else
+				throw new IllegalArgumentException(
+						"Unable to format, no UnitConverter given"); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Formats the given <code>Formattable</code> to the given StringBuffer and returns the
+	 * given precedence of the converter's mathematical operation.
+	 * 
+	 * @param f
+	 *            the formattable to be formatted
+	 * @param unitPrecedence
+	 *            the operator precedence of the operation expressed by the unit
+	 *            being modified by the given converter.
+	 * @param buffer
+	 *            the <code>StringBuffer</code> to append to.
+	 * @return the given operator precedence
+	 */
+	private int formatFormattable(Formattable f, int unitPrecedence, StringBuilder buffer) {
+		Formatter fmt = new Formatter();
+		fmt.format(Messages.LocalFormat_Pattern, f);
+		buffer.replace(0, 1, fmt.toString());
+		fmt.close(); // XXX try Java 7 with res, but for now let's leave J6 compliant
+		return unitPrecedence;
+	}
+		
+	/**
+	 * Override Format.format().
+	 * 
+	 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer,
+	 *      java.text.FieldPosition)
+	 */
+	@Override
+	public StringBuffer format(Object obj, StringBuffer toAppendTo,
+			FieldPosition pos) {
+		try {
+			Unit<?> unit = (Unit<?>) obj;
+			// fmt.setCurrency(currency.getCurrency());
+			return (StringBuffer) format(unit, toAppendTo);
+		} catch (IOException ie) {
+			throw new IllegalArgumentException(
+					"Invalid type: " + obj.getClass().getName()); //$NON-NLS-1$
+		} catch (ClassCastException e) {
+			throw new IllegalArgumentException(
+					"Invalid type: " + obj.getClass().getName()); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Override Format.parseObject().
+	 * 
+	 * @see java.text.Format#parseObject(java.lang.String,
+	 *      java.text.ParsePosition)
+	 */
+	public Object parseObject(String source, ParsePosition pos) {
+		return parse(source, pos);
+	}
+
+	public ULocale getLocale() {
+		return uLocale;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParseException.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParseException.java
new file mode 100644
index 0000000..f9cfe38
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParseException.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
+/* JavaCCOptions:KEEP_LINE_COL=null */
+package org.eclipse.uomo.units.impl.format;
+
+import static org.eclipse.uomo.units.impl.format.TokenMgrError.addEscapes;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.0.1 ($Revision: 105 $), $Date: 2010-08-05 21:44:23 +0100 (Do, 05 Aug 2010) $
+ */
+class ParseException extends RuntimeException {
+
+    /**
+     * The version identifier for this Serializable class.
+     * Increment only if the <i>serialized</i> form of the
+     * class changes.
+     */
+    private static final long serialVersionUID = 2932151235799168061L;
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+  }
+
+  /** Constructor with message. */
+  public ParseException(String message) {
+    super(message);
+  }
+
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser) the correct error message
+   * gets displayed.
+   */
+  private static String initialise(Token currentToken,
+                           int[][] expectedTokenSequences,
+                           String[] tokenImage) {
+    String eol = System.getProperty("line.separator", "\n");
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += " " + tokenImage[tok.kind];
+      retval += " \"";
+      retval += addEscapes(tok.image);
+      retval += " \"";
+      tok = tok.next;
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+
+}
+/* JavaCC - OriginalChecksum=c67b0f8ee6c642900399352b33f90efd (do not edit this line) */
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParsePrefix.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParsePrefix.java
new file mode 100644
index 0000000..a2bc372
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/ParsePrefix.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.format;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+
+
+/**
+ * This class represents the prefixes recognized when parsing/formatting.
+ *
+ * @version 1.0
+ */
+enum ParsePrefix  {
+
+    YOTTA(new RationalConverter(BigInteger.TEN.pow(24), BigInteger.ONE)),
+    ZETTA(new RationalConverter(BigInteger.TEN.pow(21), BigInteger.ONE)),
+    EXA(new RationalConverter(BigInteger.TEN.pow(18), BigInteger.ONE)),
+    PETA(new RationalConverter(BigInteger.TEN.pow(15), BigInteger.ONE)),
+    TERA(new RationalConverter(BigInteger.TEN.pow(12), BigInteger.ONE)),
+    GIGA(new RationalConverter(BigInteger.TEN.pow(9), BigInteger.ONE)),
+    MEGA(new RationalConverter(BigInteger.TEN.pow(6), BigInteger.ONE)),
+    KILO(new RationalConverter(BigInteger.TEN.pow(3), BigInteger.ONE)),
+    HECTO(new RationalConverter(BigInteger.TEN.pow(2), BigInteger.ONE)),
+    DEKA(new RationalConverter(BigInteger.TEN.pow(1), BigInteger.ONE)),
+    DECI(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(1))),
+    CENTI(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(2))),
+    MILLI(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(3))),
+    MICRO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(6))),
+    NANO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(9))),
+    PICO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(12))),
+    FEMTO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(15))),
+    ATTO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(18))),
+    ZEPTO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(21))),
+    YOCTO(new RationalConverter( BigInteger.ONE, BigInteger.TEN.pow(24)));
+
+    private final AbstractConverter converter;
+
+    /**
+     * Creates a new prefix.
+     *
+     * @param converter the associated unit converter.
+     */
+    ParsePrefix (AbstractConverter converter) {
+        this.converter = converter;
+    }
+
+    /**
+     * Returns the corresponding unit converter.
+     *
+     * @return the unit converter.
+     */
+    public AbstractConverter getConverter() {
+        return converter;
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SimpleCharStream.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SimpleCharStream.java
new file mode 100644
index 0000000..cf941ef
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SimpleCharStream.java
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.eclipse.uomo.units.impl.format;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+class SimpleCharStream
+{
+/** Whether parser is static. */
+  static final boolean staticFlag = false;
+  int bufsize;
+  int available;
+  int tokenBegin;
+/** Position in buffer. */
+  private int bufpos = -1;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+
+  protected void expandBuff(boolean wrapAround)
+  {
+    char[] newbuffer = new char[bufsize + 2048];
+    int newbufline[] = new int[bufsize + 2048];
+    int newbufcolumn[] = new int[bufsize + 2048];
+
+    try
+    {
+      if (wrapAround)
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+      }
+      else
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos -= tokenBegin);
+      }
+    }
+    catch (Throwable t)
+    {
+      throw new Error(t.getMessage());
+    }
+
+
+    bufsize += 2048;
+    available = bufsize;
+    tokenBegin = 0;
+  }
+
+  protected void fillBuff() throws java.io.IOException
+  {
+    if (maxNextCharInd == available)
+    {
+      if (available == bufsize)
+      {
+        if (tokenBegin > 2048)
+        {
+          bufpos = maxNextCharInd = 0;
+          available = tokenBegin;
+        }
+        else if (tokenBegin < 0)
+          bufpos = maxNextCharInd = 0;
+        else
+          expandBuff(false);
+      }
+      else if (available > tokenBegin)
+        available = bufsize;
+      else if ((tokenBegin - available) < 2048)
+        expandBuff(true);
+      else
+        available = tokenBegin;
+    }
+
+    int i;
+    try {
+      if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
+      {
+        inputStream.close();
+        throw new java.io.IOException();
+      }
+      else
+        maxNextCharInd += i;
+      return;
+    }
+    catch(java.io.IOException e) {
+      --bufpos;
+      backup(0);
+      if (tokenBegin == -1)
+        tokenBegin = bufpos;
+      throw e;
+    }
+  }
+
+/** Start. */
+  protected char beginToken() throws java.io.IOException
+  {
+    tokenBegin = -1;
+    char c = readChar();
+    tokenBegin = bufpos;
+
+    return c;
+  }
+
+  protected void updateLineColumn(char c)
+  {
+    column++;
+
+    if (prevCharIsLF)
+    {
+      prevCharIsLF = false;
+      line += (column = 1);
+    }
+    else if (prevCharIsCR)
+    {
+      prevCharIsCR = false;
+      if (c == '\n')
+      {
+        prevCharIsLF = true;
+      }
+      else
+        line += (column = 1);
+    }
+
+    switch (c)
+    {
+      case '\r' :
+        prevCharIsCR = true;
+        break;
+      case '\n' :
+        prevCharIsLF = true;
+        break;
+      case '\t' :
+        column--;
+        column += (tabSize - (column % tabSize));
+        break;
+      default :
+        break;
+    }
+
+    bufline[bufpos] = line;
+    bufcolumn[bufpos] = column;
+  }
+
+/** Read a character. */
+  protected char readChar() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      return buffer[bufpos];
+    }
+
+    if (++bufpos >= maxNextCharInd)
+      fillBuff();
+
+    char c = buffer[bufpos];
+
+    updateLineColumn(c);
+    return c;
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndColumn
+   */
+
+  protected int getColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndLine
+   */
+
+  protected int getLine() {
+    return bufline[bufpos];
+  }
+
+  /** Get token end column number. */
+  protected int getEndColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  /** Get token end line number. */
+  protected int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  /** Get token beginning column number. */
+  protected int getBeginColumn() {
+    return bufcolumn[tokenBegin];
+  }
+
+  /** Get token beginning line number. */
+  protected int getBeginLine() {
+    return bufline[tokenBegin];
+  }
+
+/** Backup a number of characters. */
+  protected void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+      bufpos += bufsize;
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.Reader dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.Reader dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  void reInit(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    bufpos = -1;
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.Reader dstream, int startline,
+                     int startcolumn)
+  {
+    reInit(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.Reader dstream)
+  {
+    reInit(dstream, 1, 1, 4096);
+  }
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Constructor. */
+  protected SimpleCharStream(java.io.InputStream dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    reInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream, int startline,
+                          int startcolumn, int buffersize)
+  {
+    reInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    reInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream)
+  {
+    reInit(dstream, 1, 1, 4096);
+  }
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    reInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  /** Reinitialise. */
+  protected void reInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+    reInit(dstream, startline, startcolumn, 4096);
+  }
+  /** Get token literal value. */
+  protected String getImage()
+  {
+    if (bufpos >= tokenBegin)
+      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    else
+      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                            new String(buffer, 0, bufpos + 1);
+  }
+
+  /** Get the suffix. */
+  protected char[] getSuffix(int len)
+  {
+    char[] ret = new char[len];
+
+    if ((bufpos + 1) >= len)
+      System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    else
+    {
+      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                        len - bufpos - 1);
+      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+    }
+
+    return ret;
+  }
+
+  /** Reset buffer when finished. */
+  protected void done()
+  {
+    buffer = null;
+    bufline = null;
+    bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  protected void adjustBeginLineColumn(int newLine, int newCol)
+  {
+    int start = tokenBegin;
+    int len;
+
+    if (bufpos >= tokenBegin)
+    {
+      len = bufpos - tokenBegin + inBuf + 1;
+    }
+    else
+    {
+      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+    }
+
+    int i = 0, j = 0, k = 0;
+    int nextColDiff = 0, columnDiff = 0;
+
+    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+    {
+      bufline[j] = newLine;
+      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+      bufcolumn[j] = newCol + columnDiff;
+      columnDiff = nextColDiff;
+      i++;
+    }
+
+    if (i < len)
+    {
+      bufline[j] = newLine++;
+      bufcolumn[j] = newCol + columnDiff;
+
+      while (i++ < len)
+      {
+        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+          bufline[j] = newLine++;
+        else
+          bufline[j] = newLine;
+      }
+    }
+
+    line = bufline[j];
+    column = bufcolumn[j];
+  }
+
+}
+/* JavaCC - OriginalChecksum=ec4e178f3ccf05ea2ca32d15e09312ca (do not edit this line) */
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SymbolMapImpl.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SymbolMapImpl.java
new file mode 100644
index 0000000..740a1bb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/SymbolMapImpl.java
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Eric Russell - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.format;
+
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.SymbolMap;
+import org.eclipse.uomo.units.impl.converter.MultiplyConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+
+/**
+ * <p> This class holds the default implementation of the SymbolMap
+ *     interface.</p>
+ *
+ * <p> No attempt is made to verify the uniqueness of the mappings.</p>
+ *
+ * <p> Mappings are read from a <code>ResourceBundle</code>, the keys
+ *     of which should consist of a fully-qualified class name, followed
+ *     by a dot ('.'), and then the name of a static field belonging
+ *     to that class, followed optionally by another dot and a number.
+ *     If the trailing dot and number are not present, the value
+ *     associated with the key is treated as a
+ *     {@linkplain SymbolMap#label(org.unitsofmeasure.Unit, String) label},
+ *     otherwise if the trailing dot and number are present, the value
+ *     is treated as an {@linkplain SymbolMap#alias(org.unitsofmeasure.Unit,String) alias}.
+ *     Aliases map from String to Unit only, whereas labels map in both
+ *     directions. A given unit may have any number of aliases, but may
+ *     have only one label.</p>
+ *
+ * @author <a href="mailto:eric-r@northwestern.edu">Eric Russell</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.8 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+class SymbolMapImpl implements SymbolMap {
+	// TODO fix issue with duplicate symbols (i.E. in different systems)
+    private final Map<String, Unit<?>> symbolToUnit;
+    private final Map<Unit<?>, String> unitToSymbol;
+    private final Map<String, ParsePrefix> symbolToPrefix;
+    private final Map<ParsePrefix, String> prefixToSymbol;
+    private final Map<UnitConverter, ParsePrefix> converterToPrefix;
+
+    /**
+     * Creates an empty mapping.
+     */
+    public SymbolMapImpl () {
+        symbolToUnit = new HashMap<String, Unit<?>>();
+        unitToSymbol = new HashMap<Unit<?>, String>();
+        symbolToPrefix = new HashMap<String, ParsePrefix>();
+        prefixToSymbol = new HashMap<ParsePrefix, String>();
+        converterToPrefix = new HashMap<UnitConverter, ParsePrefix>();
+    }
+
+    /**
+     * Creates a symbol map from the specified resource bundle,
+     *
+     * @param rb the resource bundle.
+     */
+    public SymbolMapImpl (ResourceBundle rb) {
+        this();
+        for (Enumeration<String> i = rb.getKeys(); i.hasMoreElements();) {
+            String fqn = i.nextElement();
+            String symbol = rb.getString(fqn);
+            boolean isAlias = false;
+            int lastDot = fqn.lastIndexOf('.');
+            String className = fqn.substring(0, lastDot);
+            String fieldName = fqn.substring(lastDot+1, fqn.length());
+            if (Character.isDigit(fieldName.charAt(0))) {
+                isAlias = true;
+                fqn = className;
+                lastDot = fqn.lastIndexOf('.');
+                className = fqn.substring(0, lastDot);
+                fieldName = fqn.substring(lastDot+1, fqn.length());
+            }
+            try {
+                Class<?> c = Class.forName(className);
+                Field field = c.getField(fieldName);
+                Object value = field.get(null);
+                if (value instanceof AbstractUnit<?>) {
+                    if (isAlias) {
+                        alias((AbstractUnit<?>)value, symbol);
+                    } else {
+                        label((AbstractUnit<?>)value, symbol);
+                    }
+                } else if (value instanceof ParsePrefix) {
+                    label((ParsePrefix)value, symbol);
+                } else {
+                    throw new ClassCastException("" + value + " to Unit or Prefix");  //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-1$
+                }
+            } catch (Exception e) {
+                System.err.println("Error reading Unit names: " + e.toString()); //$NON-NLS-1$
+            }
+        }
+    }
+
+//    public void label (Unit<?> unit, String symbol) {
+//        symbolToUnit.put(symbol, unit);
+//        unitToSymbol.put(unit, symbol);
+//    }
+//
+//    public void alias (Unit<?> unit, String symbol) {
+//        symbolToUnit.put(symbol, unit);
+//    }
+
+
+    public Unit<?> getUnit (String symbol) {
+        return symbolToUnit.get(symbol);
+    }
+
+//    public String getSymbol (Unit<?> unit) {
+//        return unitToSymbol.get(unit);
+//    }
+
+   public UnitConverter getConverter(String prefix) {
+        ParsePrefix prefixObject = symbolToPrefix.get(prefix);
+        if (prefixObject == null) return null;
+        return prefixObject.getConverter();
+    }
+
+    /**
+     * Attaches a label to the specified prefix. For example:[code]
+     *    symbolMap.label(Prefix.GIGA, "G");
+     *    symbolMap.label(Prefix.MICRO, "µ");
+     * [/code]
+     */
+    void label(ParsePrefix prefix, String symbol) {
+        symbolToPrefix.put(symbol, prefix);
+        prefixToSymbol.put(prefix, symbol);
+        converterToPrefix.put(prefix.getConverter(), prefix);
+        // adding MultiplyConverters (ensuring KILO(METRE) = METRE.multiply(1000)
+        if (prefix.getConverter() instanceof RationalConverter) {
+        	RationalConverter rc = (RationalConverter)prefix.getConverter();
+        	if (rc.getDividend() != null && BigInteger.ONE.equals(rc.getDivisor())) {
+        		converterToPrefix.put(new MultiplyConverter(rc.getDividend().doubleValue()), prefix);
+        	} else if (rc.getDivisor() != null && BigInteger.ONE.equals(rc.getDividend())) {
+        		converterToPrefix.put(new MultiplyConverter(1d / rc.getDivisor().doubleValue()), prefix);
+        	}
+        }
+    }
+
+    /**
+     * Returns the prefix (if any) for the specified symbol.
+     *
+     * @param symbol the unit symbol.
+     * @return the corresponding prefix or <code>null</code> if none.
+     */
+    ParsePrefix getPrefix (String symbol) {
+        for (Iterator<String> i = symbolToPrefix.keySet().iterator(); i.hasNext(); ) {
+            String pfSymbol = i.next();
+            if (symbol.startsWith(pfSymbol)) {
+                return symbolToPrefix.get(pfSymbol);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the prefix for the specified converter.
+     *
+     * @param converter the unit converter.
+     * @return the corresponding prefix or <code>null</code> if none.
+     */
+    ParsePrefix getPrefixObject (UnitConverter converter) {
+        return converterToPrefix.get(converter);
+    }
+
+    /**
+     * Returns the symbol for the specified prefix.
+     *
+     * @param prefix the prefix.
+     * @return the corresponding symbol or <code>null</code> if none.
+     */
+    String getSymbol (ParsePrefix prefix) {
+        return prefixToSymbol.get(prefix);
+    }
+
+	public void alias(Unit<?> unit, String symbol) {
+		symbolToUnit.put(symbol, unit);
+	}
+
+	public String getPrefix(UnitConverter converter) {
+        ParsePrefix prefix = getPrefixObject(converter);
+        if (prefix == null) return null;
+        return prefixToSymbol.get(prefix);
+	}
+
+	public String getSymbol(Unit<?> unit) {
+		return unitToSymbol.get(unit);
+	}
+
+	public void label(Unit<?> unit, String symbol) {
+        symbolToUnit.put(symbol, unit);
+        unitToSymbol.put(unit, symbol);
+	}
+
+	public void prefix(UnitConverter cvtr, String prefix) {
+		throw new UnsupportedOperationException("Prefixes are not modifiable"); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/Token.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/Token.java
new file mode 100644
index 0000000..0323547
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/Token.java
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.eclipse.uomo.units.impl.format;
+
+/**
+ * Describes the input token stream.
+ */
+
+class Token implements java.io.Serializable {
+
+     /**
+      * The version identifier for this Serializable class.
+      * Increment only if the <i>serialized</i> form of the
+      * class changes.
+      */
+    private static final long serialVersionUID = 2188279658897600591L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  int kind;
+
+  /** The line number of the first character of this Token. */
+  int beginLine;
+  /** The column number of the first character of this Token. */
+  int beginColumn;
+  /** The line number of the last character of this Token. */
+  int endLine;
+  /** The column number of the last character of this Token. */
+  int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=08d08345e10cca30522247698d4478e6 (do not edit this line) */
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/TokenMgrError.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/TokenMgrError.java
new file mode 100644
index 0000000..d48cbb2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/TokenMgrError.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+package org.eclipse.uomo.units.impl.format;
+
+/** Token Manager Error. */
+class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+    private static final long serialVersionUID = -3348968864772188432L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  static String lexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+    this(lexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=8a6e5be586cca28053ad55584e013006 (do not edit this line) */
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitFormatServiceImpl.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitFormatServiceImpl.java
new file mode 100644
index 0000000..e3649fd
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitFormatServiceImpl.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.format;
+
+import java.util.Locale;
+
+import org.eclipse.uomo.units.AbstractFormat;
+import org.unitsofmeasurement.service.UnitFormatService;
+import org.unitsofmeasurement.unit.UnitFormat;
+
+import com.ibm.icu.util.ULocale;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.5 ($Revision: 308 $), $Date: 2010-11-02 15:56:52 +0000 (Di, 02 Nov 2010) $
+ */
+public class UnitFormatServiceImpl implements UnitFormatService {
+
+	@Override
+	public UnitFormat getUnitFormat() {
+		return AbstractFormat.getUnitFormat();
+	}
+
+	@Override
+	public UnitFormat getUnitFormat(String name) {
+		return getUnitFormat();
+	}
+
+	@Override
+	public UnitFormat getUnitFormat(Locale locale) {
+		return AbstractFormat.getUnitFormat(ULocale.forLocale(locale));
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParser.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParser.java
new file mode 100644
index 0000000..854ee00
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParser.java
@@ -0,0 +1,771 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. UnitParser.java */
+package org.eclipse.uomo.units.impl.format;
+
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.impl.converter.LogConverter;
+import org.unitsofmeasurement.unit.Unit;
+
+/** */
+class UnitParser implements UnitParserConstants {
+
+    private static class Exponent {
+        final int pow;
+        final int root;
+        public Exponent (int pow, int root) {
+            this.pow = pow;
+            this.root = root;
+        }
+    }
+
+    private SymbolMapImpl symbols;
+
+    UnitParser (SymbolMapImpl symbols, java.io.Reader in) {
+        this(in);
+        this.symbols = symbols;
+    }
+
+//
+// Parser productions
+//
+    @SuppressWarnings("unused")
+	Unit<?> parseUnit() throws ParseException {
+        Unit<?> result;
+    result = compoundExpr();
+    jj_consume_token(0);
+        {if (true) return result;}
+    throw new Error("Missing return statement in function");
+  }
+
+  @SuppressWarnings("unused")
+Unit<?> compoundExpr() throws ParseException {
+        Unit<?> result = AbstractUnit.ONE;
+        result = addExpr();
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COLON:
+        ;
+        break;
+      default:
+        jj_la1[0] = jj_gen;
+        break label_1;
+      }
+      jj_consume_token(COLON);
+    }
+      {if (true) return result;}
+    throw new Error("Missing return statement in function");
+  }
+
+  @SuppressWarnings("unused")
+Unit<?> addExpr() throws ParseException {
+        Unit<?> result = AbstractUnit.ONE;
+        Number n1 = null;
+        Token sign1 = null;
+        Number n2 = null;
+        Token sign2 = null;
+    if (jj_2_1(2147483647)) {
+      n1 = numberExpr();
+      sign1 = sign();
+    } else {
+      ;
+    }
+    result = mulExpr();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case PLUS:
+    case MINUS:
+      sign2 = sign();
+      n2 = numberExpr();
+      break;
+    default:
+      jj_la1[1] = jj_gen;
+      ;
+    }
+        if (n1 != null) {
+            if (sign1.image.equals("-")) {
+                result = result.multiply(-1);
+            }
+            result = result.add(n1.doubleValue());
+        }
+        if (n2 != null) {
+            double offset = n2.doubleValue();
+            if (sign2.image.equals("-")) {
+                offset = -offset;
+            }
+            result = result.add(offset);
+        }
+        {if (true) return result;}
+    throw new Error("Missing return statement in function");
+  }
+
+    Unit<?> mulExpr() throws ParseException {
+        Unit<?> result = AbstractUnit.ONE;
+        Unit<?> temp = AbstractUnit.ONE;
+    result = exponentExpr();
+    label_2:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ASTERISK:
+      case MIDDLE_DOT:
+      case SOLIDUS:
+        ;
+        break;
+      default:
+        jj_la1[2] = jj_gen;
+        break label_2;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ASTERISK:
+      case MIDDLE_DOT:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case ASTERISK:
+          jj_consume_token(ASTERISK);
+          break;
+        case MIDDLE_DOT:
+          jj_consume_token(MIDDLE_DOT);
+          break;
+        default:
+          jj_la1[3] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        temp = exponentExpr();
+                                                          result=result.multiply(temp);
+        break;
+      case SOLIDUS:
+        jj_consume_token(SOLIDUS);
+        temp = exponentExpr();
+                                        result=result.divide(temp);
+        break;
+      default:
+        jj_la1[4] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+      //{if (true) 
+    	  return result;//}
+//    throw new Error("Missing return statement in function");
+  }
+
+    @SuppressWarnings("unused")
+	Unit<?> exponentExpr() throws ParseException {
+        Unit<?> result = AbstractUnit.ONE;
+        Exponent exponent = null;
+        Token token = null;
+    if (jj_2_2(2147483647)) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case INTEGER:
+        token = jj_consume_token(INTEGER);
+        break;
+      case E:
+        token = jj_consume_token(E);
+        break;
+      default:
+        jj_la1[5] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jj_consume_token(CARET);
+      result = atomicExpr();
+        double base;
+        if (token.kind == INTEGER) {
+            base = Integer.parseInt(token.image);
+        } else {
+            base = StrictMath.E;
+        }
+        {if (true) return result.transform(new LogConverter(base).inverse());}
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case OPEN_PAREN:
+      case INTEGER:
+      case FLOATING_POINT:
+      case UNIT_IDENTIFIER:
+        result = atomicExpr();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case CARET:
+        case SUPERSCRIPT_INTEGER:
+          exponent = exp();
+          break;
+        default:
+          jj_la1[6] = jj_gen;
+          ;
+        }
+        if (exponent != null) {
+            if (exponent.pow != 1) {
+                result = result.pow(exponent.pow);
+            }
+            if (exponent.root != 1) {
+                result = result.root(exponent.root);
+            }
+        }
+        {if (true) return result;}
+//        break;
+      case LOG:
+      case NAT_LOG:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LOG:
+          jj_consume_token(LOG);
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case INTEGER:
+            token = jj_consume_token(INTEGER);
+            break;
+          default:
+            jj_la1[7] = jj_gen;
+            ;
+          }
+          break;
+        case NAT_LOG:
+          token = jj_consume_token(NAT_LOG);
+          break;
+        default:
+          jj_la1[8] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        jj_consume_token(OPEN_PAREN);
+        result = addExpr();
+        jj_consume_token(CLOSE_PAREN);
+        double base = 10;
+        if (token != null) {
+            if (token.kind == INTEGER) {
+                base = Integer.parseInt(token.image);
+            } else if (token.kind == NAT_LOG) {
+                base = StrictMath.E;
+            }
+        }
+        {if (true) return result.transform(new LogConverter(base));}
+      default:
+        jj_la1[9] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  Unit<?> atomicExpr() throws ParseException {
+        Unit<?> result = AbstractUnit.ONE;
+//        Unit<?> temp = AbstractUnit.ONE;
+        Number n = null;
+        Token token = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER:
+    case FLOATING_POINT:
+      n = numberExpr();
+        if (n instanceof Integer) {
+            {if (true) return result.multiply(n.intValue());}
+        } else {
+            {if (true) return result.multiply(n.doubleValue());}
+        }
+//      break;
+    case UNIT_IDENTIFIER:
+      token = jj_consume_token(UNIT_IDENTIFIER);
+        Unit<?> unit = symbols.getUnit(token.image);
+        if (unit == null) {
+            ParsePrefix prefix = symbols.getPrefix(token.image);
+            if (prefix != null) {
+                String prefixSymbol = symbols.getSymbol(prefix);
+                unit = symbols.getUnit(token.image.substring(prefixSymbol.length()));
+                if (unit != null) {
+                    {if (true) return unit.transform(prefix.getConverter());}
+                }
+            }
+            {if (true) throw new ParseException();}
+        } else {
+            {if (true) return unit;}
+        }
+//      break;
+    case OPEN_PAREN:
+      jj_consume_token(OPEN_PAREN);
+      result = addExpr();
+      jj_consume_token(CLOSE_PAREN);
+        {if (true) return result;}
+//      break;
+    default:
+      jj_la1[10] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+//    throw new Error("Missing return statement in function");
+  }
+
+  @SuppressWarnings("unused")
+Token sign() throws ParseException {
+        Token result = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case PLUS:
+      result = jj_consume_token(PLUS);
+      break;
+    case MINUS:
+      result = jj_consume_token(MINUS);
+      break;
+    default:
+      jj_la1[11] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return result;}
+    throw new Error("Missing return statement in function");
+  }
+
+  Number numberExpr() throws ParseException {
+        Token token = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER:
+      token = jj_consume_token(INTEGER);
+        {if (true) return Long.valueOf(token.image);}
+//      break;
+    case FLOATING_POINT:
+      token = jj_consume_token(FLOATING_POINT);
+        {if (true) return Double.valueOf(token.image);}
+//      break;
+    default:
+      jj_la1[12] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+//    throw new Error("Missing return statement in function");
+  }
+
+  Exponent exp() throws ParseException {
+        Token powSign = null;
+        Token powToken = null;
+        Token rootSign = null;
+        Token rootToken = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case CARET:
+      jj_consume_token(CARET);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PLUS:
+      case MINUS:
+      case INTEGER:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case PLUS:
+        case MINUS:
+          powSign = sign();
+          break;
+        default:
+          jj_la1[13] = jj_gen;
+          ;
+        }
+        powToken = jj_consume_token(INTEGER);
+            int pow = Integer.parseInt(powToken.image);
+            if ((powSign != null) && powSign.image.equals("-")) {
+                pow = -pow;
+            }
+            {if (true) return new Exponent(pow, 1);}
+      case OPEN_PAREN:
+        jj_consume_token(OPEN_PAREN);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case PLUS:
+        case MINUS:
+          powSign = sign();
+          break;
+        default:
+          jj_la1[14] = jj_gen;
+          ;
+        }
+        powToken = jj_consume_token(INTEGER);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case SOLIDUS:
+          jj_consume_token(SOLIDUS);
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case PLUS:
+          case MINUS:
+            rootSign = sign();
+            break;
+          default:
+            jj_la1[15] = jj_gen;
+            ;
+          }
+          rootToken = jj_consume_token(INTEGER);
+          break;
+        default:
+          jj_la1[16] = jj_gen;
+          ;
+        }
+        jj_consume_token(CLOSE_PAREN);
+            pow = Integer.parseInt(powToken.image);
+            if ((powSign != null) && powSign.image.equals("-")) {
+                pow = -pow;
+            }
+            int root = 1;
+            if (rootToken != null) {
+                root = Integer.parseInt(rootToken.image);
+                if ((rootSign != null) && rootSign.image.equals("-")) {
+                    root = -root;
+                }
+            }
+            {if (true) return new Exponent(pow, root);}
+      default:
+        jj_la1[17] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    case SUPERSCRIPT_INTEGER:
+      powToken = jj_consume_token(SUPERSCRIPT_INTEGER);
+        int pow = 0;
+        for (int i = 0; i < powToken.image.length(); i += 1) {
+            pow *= 10;
+            switch (powToken.image.charAt(i)) {
+                case '\u00b9': pow += 1; break;
+                case '\u00b2': pow += 2; break;
+                case '\u00b3': pow += 3; break;
+                case '\u2074': pow += 4; break;
+                case '\u2075': pow += 5; break;
+                case '\u2076': pow += 6; break;
+                case '\u2077': pow += 7; break;
+                case '\u2078': pow += 8; break;
+                case '\u2079': pow += 9; break;
+            }
+        }
+        {if (true) return new Exponent(pow, 1);}
+//      break;
+    default:
+      jj_la1[18] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+//    throw new Error("Missing return statement in function");
+  }
+
+  private boolean jj_2_1(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  private boolean jj_3R_3() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_5()) {
+    jj_scanpos = xsp;
+    if (jj_3R_6()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_6() {
+    if (jj_scan_token(FLOATING_POINT)) return true;
+    return false;
+  }
+
+  private boolean jj_3_2() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(14)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(19)) return true;
+    }
+    if (jj_scan_token(CARET)) return true;
+    return false;
+  }
+
+  private boolean jj_3_1() {
+    if (jj_3R_3()) return true;
+    if (jj_3R_4()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_4() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(5)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(6)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_5() {
+    if (jj_scan_token(INTEGER)) return true;
+    return false;
+  }
+
+  /** Generated Token Manager. */
+  private UnitParserTokenManager token_source;
+  private SimpleCharStream jj_input_stream;
+  /** Current token. */
+  private Token token;
+  /** Next token. */
+  private Token jj_nt;
+  private int jj_ntk;
+  private Token jj_scanpos, jj_lastpos;
+  private int jj_la;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[19];
+  static private int[] jj_la1_0;
+  static {
+      jj_la1_init_0();
+   }
+   private static void jj_la1_init_0() {
+      jj_la1_0 = new int[] {0x800,0x60,0x380,0x180,0x380,0x84000,0x8400,0x4000,0x60000,0x175000,0x115000,0x60,0x14000,0x60,0x60,0x60,0x200,0x5060,0x8400,};
+   }
+  final private JJCalls[] jj_2_rtns = new JJCalls[2];
+  private boolean jj_rescan = false;
+  private int jj_gc = 0;
+
+  /** Constructor with InputStream. */
+  UnitParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  /** Constructor with InputStream and supplied encoding */
+  UnitParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new UnitParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 19; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor. */
+  UnitParser(java.io.Reader stream) {
+    jj_input_stream = new SimpleCharStream(stream, 1, 1);
+    token_source = new UnitParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 19; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+//  private void reInit(java.io.Reader stream) {
+//    jj_input_stream.reInit(stream, 1, 1);
+//    token_source.reInit(jj_input_stream);
+//    token = new Token();
+//    jj_ntk = -1;
+//    jj_gen = 0;
+//    for (int i = 0; i < 19; i++) jj_la1[i] = -1;
+//    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+//  }
+
+  /** Constructor with generated Token Manager. */
+  UnitParser(UnitParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 19; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+//  private void reInit(UnitParserTokenManager tm) {
+//    token_source = tm;
+//    token = new Token();
+//    jj_ntk = -1;
+//    jj_gen = 0;
+//    for (int i = 0; i < 19; i++) jj_la1[i] = -1;
+//    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+//  }
+
+  private Token jj_consume_token(int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (int i = 0; i < jj_2_rtns.length; i++) {
+          JJCalls c = jj_2_rtns[i];
+          while (c != null) {
+            if (c.gen < jj_gen) c.first = null;
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  static private final class LookaheadSuccess extends java.lang.Error {
+
+  /**
+   *
+   */
+  private static final long serialVersionUID = -8192240240676284081L; }
+  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+  private boolean jj_scan_token(int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) jj_add_error_token(kind, i);
+    }
+    if (jj_scanpos.kind != kind) return true;
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+    return false;
+  }
+
+
+/** Get the next Token. */
+  final Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+/** Get the specific Token. */
+  final Token getToken(int index) {
+    Token t = token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+  private int[] jj_lasttokens = new int[100];
+  private int jj_endpos;
+
+  private void jj_add_error_token(int kind, int pos) {
+    if (pos >= 100) return;
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+      jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
+        int[] oldentry = (int[])(it.next());
+        if (oldentry.length == jj_expentry.length) {
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              continue jj_entries_loop;
+            }
+          }
+          jj_expentries.add(jj_expentry);
+          break jj_entries_loop;
+        }
+      }
+      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+    }
+  }
+
+  /** Generate ParseException. */
+  ParseException generateParseException() {
+    jj_expentries.clear();
+    boolean[] la1tokens = new boolean[21];
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 19; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 21; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.add(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = jj_expentries.get(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  /** Enable tracing. */
+  final void enable_tracing() {
+  }
+
+  /** Disable tracing. */
+  final void disable_tracing() {
+  }
+
+  private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 2; i++) {
+    try {
+      JJCalls p = jj_2_rtns[i];
+      do {
+        if (p.gen > jj_gen) {
+          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+          switch (i) {
+            case 0: jj_3_1(); break;
+            case 1: jj_3_2(); break;
+          }
+        }
+        p = p.next;
+      } while (p != null);
+      } catch(LookaheadSuccess ls) { }
+    }
+    jj_rescan = false;
+  }
+
+  private void jj_save(int index, int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+  }
+
+  static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserConstants.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserConstants.java
new file mode 100644
index 0000000..121d67d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserConstants.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. UnitParserConstants.java */
+package org.eclipse.uomo.units.impl.format;
+
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+interface UnitParserConstants {
+
+  /** End of File. */
+  int EOF = 0;
+  /** RegularExpression Id. */
+  int DIGIT = 1;
+  /** RegularExpression Id. */
+  int SUPERSCRIPT_DIGIT = 2;
+  /** RegularExpression Id. */
+  int INITIAL_CHAR = 3;
+  /** RegularExpression Id. */
+  int EXTENDED_CHAR = 4;
+  /** RegularExpression Id. */
+  int PLUS = 5;
+  /** RegularExpression Id. */
+  int MINUS = 6;
+  /** RegularExpression Id. */
+  int ASTERISK = 7;
+  /** RegularExpression Id. */
+  int MIDDLE_DOT = 8;
+  /** RegularExpression Id. */
+  int SOLIDUS = 9;
+  /** RegularExpression Id. */
+  int CARET = 10;
+  /** RegularExpression Id. */
+  int COLON = 11;
+  /** RegularExpression Id. */
+  int OPEN_PAREN = 12;
+  /** RegularExpression Id. */
+  int CLOSE_PAREN = 13;
+  /** RegularExpression Id. */
+  int INTEGER = 14;
+  /** RegularExpression Id. */
+  int SUPERSCRIPT_INTEGER = 15;
+  /** RegularExpression Id. */
+  int FLOATING_POINT = 16;
+  /** RegularExpression Id. */
+  int LOG = 17;
+  /** RegularExpression Id. */
+  int NAT_LOG = 18;
+  /** RegularExpression Id. */
+  int E = 19;
+  /** RegularExpression Id. */
+  int UNIT_IDENTIFIER = 20;
+
+  /** Lexical state. */
+  int DEFAULT = 0;
+
+  /** Literal token values. */
+  String[] tokenImage = {
+    "<EOF>",
+    "<DIGIT>",
+    "<SUPERSCRIPT_DIGIT>",
+    "<INITIAL_CHAR>",
+    "<EXTENDED_CHAR>",
+    "\"+\"",
+    "\"-\"",
+    "\"*\"",
+    "\"\\u00b7\"",
+    "\"/\"",
+    "\"^\"",
+    "\":\"",
+    "\"(\"",
+    "\")\"",
+    "<INTEGER>",
+    "<SUPERSCRIPT_INTEGER>",
+    "<FLOATING_POINT>",
+    "<LOG>",
+    "<NAT_LOG>",
+    "\"e\"",
+    "<UNIT_IDENTIFIER>",
+  };
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserTokenManager.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserTokenManager.java
new file mode 100644
index 0000000..5316ad3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/format/UnitParserTokenManager.java
@@ -0,0 +1,482 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/* Generated By:JavaCC: Do not edit this line. UnitParserTokenManager.java */
+package org.eclipse.uomo.units.impl.format;
+
+/** Token Manager. */
+class UnitParserTokenManager implements UnitParserConstants
+{
+
+  /** Debug output. */
+  java.io.PrintStream debugStream = System.out;
+  /** Set debug output. */
+  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+//private final int jjStopStringLiteralDfa_0(int pos, long active0)
+//{
+//   switch (pos)
+//   {
+//      default :
+//         return -1;
+//   }
+//}
+//private final int jjStartNfa_0(int pos, long active0)
+//{
+//   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+//}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 40:
+         return jjStopAtPos(0, 12);
+      case 41:
+         return jjStopAtPos(0, 13);
+      case 42:
+         return jjStopAtPos(0, 7);
+      case 43:
+         return jjStopAtPos(0, 5);
+      case 45:
+         return jjStopAtPos(0, 6);
+      case 47:
+         return jjStopAtPos(0, 9);
+      case 58:
+         return jjStopAtPos(0, 11);
+      case 94:
+         return jjStopAtPos(0, 10);
+      case 101:
+         return jjStartNfaWithStates_0(0, 19, 7);
+      case 183:
+         return jjStopAtPos(0, 8);
+      default :
+         return jjMoveNfa_0(6, 0);
+   }
+}
+private int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_0(state, pos + 1);
+}
+static final long[] jjbitVec0 = {
+   0x0L, 0x0L, 0x20c000000000000L, 0x0L
+};
+static final long[] jjbitVec1 = {
+   0x0L, 0x3f1000000000000L, 0x0L, 0x0L
+};
+static final long[] jjbitVec2 = {
+   0xfffffffefffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec4 = {
+   0x0L, 0x0L, 0xfd73ffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec5 = {
+   0xffffffffffffffffL, 0xfc0effffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 15;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 6:
+                  if ((0xf80010fe00000000L & l) != 0L)
+                  {
+                     if (kind > 20)
+                        kind = 20;
+                     jjCheckNAdd(7);
+                  }
+                  else if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 14)
+                        kind = 14;
+                     jjCheckNAddStates(0, 4);
+                  }
+                  else if (curChar == 46)
+                     jjCheckNAdd(2);
+                  break;
+               case 1:
+                  if (curChar == 46)
+                     jjCheckNAdd(2);
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 16)
+                     kind = 16;
+                  jjCheckNAddTwoStates(2, 3);
+                  break;
+               case 4:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(5);
+                  break;
+               case 5:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 16)
+                     kind = 16;
+                  jjCheckNAdd(5);
+                  break;
+               case 7:
+                  if ((0xfbff10fe00000000L & l) == 0L)
+                     break;
+                  if (kind > 20)
+                     kind = 20;
+                  jjCheckNAdd(7);
+                  break;
+               case 8:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 14)
+                     kind = 14;
+                  jjCheckNAddStates(0, 4);
+                  break;
+               case 9:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 14)
+                     kind = 14;
+                  jjCheckNAdd(9);
+                  break;
+               case 10:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 16)
+                     kind = 16;
+                  jjCheckNAddStates(5, 8);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 6:
+                  if ((0xffffffffbfffffffL & l) != 0L)
+                  {
+                     if (kind > 20)
+                        kind = 20;
+                     jjCheckNAdd(7);
+                  }
+                  if (curChar == 108)
+                     jjAddStates(9, 10);
+                  break;
+               case 3:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(11, 12);
+                  break;
+               case 7:
+                  if ((0xffffffffbfffffffL & l) == 0L)
+                     break;
+                  if (kind > 20)
+                     kind = 20;
+                  jjCheckNAdd(7);
+                  break;
+               case 11:
+                  if (curChar == 108)
+                     jjAddStates(9, 10);
+                  break;
+               case 12:
+                  if (curChar == 111)
+                     jjstateSet[jjnewStateCnt++] = 13;
+                  break;
+               case 13:
+                  if (curChar == 103 && kind > 17)
+                     kind = 17;
+                  break;
+               case 14:
+                  if (curChar == 110 && kind > 18)
+                     kind = 18;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 6:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                  {
+                     if (kind > 15)
+                        kind = 15;
+                     jjCheckNAdd(0);
+                  }
+                  if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+                  {
+                     if (kind > 20)
+                        kind = 20;
+                     jjCheckNAdd(7);
+                  }
+                  break;
+               case 0:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 15)
+                     kind = 15;
+                  jjCheckNAdd(0);
+                  break;
+               case 7:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 20)
+                     kind = 20;
+                  jjCheckNAdd(7);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 15 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+   9, 1, 2, 3, 10, 1, 2, 3, 10, 12, 14, 4, 5,
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec1[i2] & l2) != 0L);
+      default :
+         return false;
+   }
+}
+private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec4[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec2[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+
+/** Token literal values. */
+private static final String[] jjstrLiteralImages = {
+"", null, null, null, null, "\53", "\55", "\52", "\267", "\57", "\136", "\72",
+"\50", "\51", null, null, null, null, null, "\145", null, };
+
+/** Lexer state names. */
+//private static final String[] lexStateNames = {
+//   "DEFAULT",
+//};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[15];
+private final int[] jjstateSet = new int[30];
+protected char curChar;
+/** Constructor. */
+UnitParserTokenManager(SimpleCharStream stream){
+   if (SimpleCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+
+/** Constructor. */
+UnitParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   switchTo(lexState);
+}
+
+/** Reinitialise parser. */
+void reInit(SimpleCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 15; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+
+/** Reinitialise parser. */
+void reInit(SimpleCharStream stream, int lexState)
+{
+   reInit(stream);
+   switchTo(lexState);
+}
+
+/** Switch to specified lex state. */
+void switchTo(int lexState)
+{
+   if (lexState >= 1 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   final Token t;
+   final String curTokenImage;
+   final int beginLine;
+   final int endLine;
+   final int beginColumn;
+   final int endColumn;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   curTokenImage = (im == null) ? input_stream.getImage() : im;
+   beginLine = input_stream.getBeginLine();
+   beginColumn = input_stream.getBeginColumn();
+   endLine = input_stream.getEndLine();
+   endColumn = input_stream.getEndColumn();
+   t = Token.newToken(jjmatchedKind, curTokenImage);
+
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
+
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+Token getNextToken()
+{
+  Token matchedToken;
+  int curPos = 0;
+
+//  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.beginToken();
+   }
+   catch(java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      return matchedToken;
+   }
+
+   jjmatchedKind = 0x7fffffff;
+   jjmatchedPos = 0;
+   curPos = jjMoveStringLiteralDfa0_0();
+   if (jjmatchedKind != 0x7fffffff)
+   {
+      if (jjmatchedPos + 1 < curPos)
+         input_stream.backup(curPos - jjmatchedPos - 1);
+         matchedToken = jjFillToken();
+         return matchedToken;
+   }
+   int error_line = input_stream.getEndLine();
+   int error_column = input_stream.getEndColumn();
+   String error_after = null;
+   boolean EOFSeen = false;
+   try { input_stream.readChar(); input_stream.backup(1); }
+   catch (java.io.IOException e1) {
+      EOFSeen = true;
+      error_after = curPos <= 1 ? "" : input_stream.getImage();
+      if (curChar == '\n' || curChar == '\r') {
+         error_line++;
+         error_column = 0;
+      }
+      else
+         error_column++;
+   }
+   if (!EOFSeen) {
+      input_stream.backup(1);
+      error_after = curPos <= 1 ? "" : input_stream.getImage();
+   }
+   throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+  }
+}
+
+private void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+
+private void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AccelerationAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AccelerationAmount.java
new file mode 100644
index 0000000..9c6c937
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AccelerationAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Jean-Marie Dautelle and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Acceleration;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Represents the rate of change of velocity with respect to time.
+ * The metric system unit for this quantity is "m/s²" (metre per square second).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.5, $Date: 2013-04-28 $
+ */
+public final class AccelerationAmount extends BaseAmount<Acceleration> implements Acceleration {
+	
+	public AccelerationAmount(Number number, Unit<Acceleration> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AngleAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AngleAmount.java
new file mode 100644
index 0000000..caeb434
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AngleAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Angle;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Represents the figure formed by two lines diverging from a common point.
+ * The metric system unit for this quantity is "rad" (radian).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, $Date: 2013-04-28 $
+ */
+public final class AngleAmount extends BaseAmount<Angle> {
+	
+	public AngleAmount(Number number, Unit<Angle> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AreaAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AreaAmount.java
new file mode 100644
index 0000000..548f8d5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/AreaAmount.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Area;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Represents the extent of a planar region or of the surface of
+ * a solid measured in square units.
+ * The metric system unit for this quantity is "m²" (square metre).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4, $Date: 2013-04-28 $
+ */
+public final class AreaAmount extends BaseAmount<Area> {
+
+	public AreaAmount(Number number, Unit<Area> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/CatalyticActivityAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/CatalyticActivityAmount.java
new file mode 100644
index 0000000..e8ed0a2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/CatalyticActivityAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.CatalyticActivity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a catalytic activity.
+ * The metric system unit for this quantity is "kat" (katal).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, $Date: 2013-04-28 $
+ */
+public final class CatalyticActivityAmount extends BaseAmount<CatalyticActivity> {
+
+	public CatalyticActivityAmount(Number number, Unit<CatalyticActivity> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCapacitanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCapacitanceAmount.java
new file mode 100644
index 0000000..27eaf79
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCapacitanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricCapacitance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an electric capacitance.
+ * The metric system unit for this quantity is "F" (Farad).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-04-28 $
+ */
+public final class ElectricCapacitanceAmount extends BaseAmount<ElectricCapacitance> {
+
+	public ElectricCapacitanceAmount(Number number, Unit<ElectricCapacitance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricChargeAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricChargeAmount.java
new file mode 100644
index 0000000..640ca4d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricChargeAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricCharge;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an electric charge.
+ * The metric system unit for this quantity is "C" (Coulomb).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-04-28 $
+ */
+public final class ElectricChargeAmount extends BaseAmount<ElectricCharge> {
+
+	public ElectricChargeAmount(Number number, Unit<ElectricCharge> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricConductanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricConductanceAmount.java
new file mode 100644
index 0000000..99dbf22
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricConductanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricConductance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an electric conductance amount.
+ * The metric system unit for this quantity "S" (Siemens).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-11 $
+ */
+public final class ElectricConductanceAmount extends BaseAmount<ElectricConductance> {
+
+	public ElectricConductanceAmount(Number number, Unit<ElectricConductance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCurrentAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCurrentAmount.java
new file mode 100644
index 0000000..3c3a699
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricCurrentAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricCurrent;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the amount of electric charge flowing past
+ * a specified circuit point per unit time.
+ * The metric system unit for this quantity is "A" (Ampere).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-12 $
+ */
+public final class ElectricCurrentAmount extends BaseAmount<ElectricCurrent> {
+
+	public ElectricCurrentAmount(Number number, Unit<ElectricCurrent> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricInductanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricInductanceAmount.java
new file mode 100644
index 0000000..d5bd948
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricInductanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricInductance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an electric inductance.
+ * The metric system unit for this quantity is "H" (Henry).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public final class ElectricInductanceAmount extends BaseAmount<ElectricInductance> {
+
+	public ElectricInductanceAmount(Number number, Unit<ElectricInductance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricPotentialAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricPotentialAmount.java
new file mode 100644
index 0000000..884dabb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricPotentialAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricPotential;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an amount of electric potential or electromotive force.
+ * The metric system unit for this quantity is "V" (Volt).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-13 $
+ */
+public final class ElectricPotentialAmount extends BaseAmount<ElectricPotential> {
+
+	public ElectricPotentialAmount(Number number, Unit<ElectricPotential> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricResistanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricResistanceAmount.java
new file mode 100644
index 0000000..de46f36
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ElectricResistanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.ElectricResistance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an electric resistance.
+ * The metric system unit for this quantity is "Ohm" (Ω).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-13 $
+ */
+public final class ElectricResistanceAmount extends BaseAmount<ElectricResistance> {
+
+	public ElectricResistanceAmount(Number number, Unit<ElectricResistance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/EnergyAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/EnergyAmount.java
new file mode 100644
index 0000000..86c4c3c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/EnergyAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Energy;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the capacity of a physical system to do work.
+ * The metric system unit for this quantity "J" (Joule).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, $Date: 2013-05-20 $
+ */
+public final class EnergyAmount extends BaseAmount<Energy> implements Energy {
+
+	public EnergyAmount(Number number, Unit<Energy> unit) {
+		super(number, unit);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ForceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ForceAmount.java
new file mode 100644
index 0000000..fc69f8c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/ForceAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Force;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a quantity that tends to produce an acceleration of a body in the
+ * direction of its application. The metric system unit for this quantity is "N"
+ * (Newton).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, $Date: 2013-05-21 $
+ */
+public final class ForceAmount extends BaseAmount<Force> implements Force {
+
+	public ForceAmount(Number number, Unit<Force> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/FrequencyAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/FrequencyAmount.java
new file mode 100644
index 0000000..49306a1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/FrequencyAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Frequency;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the number of times a specified phenomenon occurs within a specified interval.
+ * The metric system unit for this quantity is "Hz" (Hertz).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public final class FrequencyAmount extends BaseAmount<Frequency> {
+
+	public FrequencyAmount(Number number, Unit<Frequency> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IlluminanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IlluminanceAmount.java
new file mode 100644
index 0000000..a2b0691
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IlluminanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Illuminance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an illuminance.
+ * The metric system unit for this quantity is "lx" (lux).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public final class IlluminanceAmount extends BaseAmount<Illuminance> {
+
+	public IlluminanceAmount(Number number, Unit<Illuminance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/InformationAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/InformationAmount.java
new file mode 100644
index 0000000..1fc96d2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/InformationAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Information;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a measure of data amount. The metric system unit for this quantity
+ * is "bit".
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.5, $Date: 2013-05-21 $
+ */
+public final class InformationAmount extends BaseAmount<Information> implements
+		Information {
+
+	public InformationAmount(Number number, Unit<Information> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IonizingRadiationAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IonizingRadiationAmount.java
new file mode 100644
index 0000000..189528a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/IonizingRadiationAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.IonizingRadiation;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the quantity of subatomic particles or electromagnetic waves that
+ * are energetic enough to detach electrons from atoms or molecules, ionizing
+ * them. The system unit for this quantity is "C/kg ("coulomb per kilogram).
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1, $Date: 2013-05-21 $
+ */
+public final class IonizingRadiationAmount extends BaseAmount<IonizingRadiation>
+		implements IonizingRadiation {
+
+	public IonizingRadiationAmount(Number number, Unit<IonizingRadiation> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LengthAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LengthAmount.java
new file mode 100644
index 0000000..e3e76e2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LengthAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the extent of something along its greatest
+ * dimension or the extent of space between two objects or places.
+ * The metric system unit for this quantity is "m" (metre).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.5, $Date: 2013-05-21 $
+ */
+public final class LengthAmount extends BaseAmount<Length> implements Length {
+
+	public LengthAmount(Number number, Unit<Length> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousFluxAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousFluxAmount.java
new file mode 100644
index 0000000..32b006c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousFluxAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.LuminousFlux;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a luminous flux. The metric system unit for this quantity is "lm"
+ * (lumen).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public final class LuminousFluxAmount extends BaseAmount<LuminousFlux>
+		implements LuminousFlux {
+
+	public LuminousFluxAmount(Number number, Unit<LuminousFlux> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousIntensityAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousIntensityAmount.java
new file mode 100644
index 0000000..faecc6e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/LuminousIntensityAmount.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.LuminousIntensity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the luminous flux density per solid angle as measured in a given
+ * direction relative to the emitting source. The metric system unit for this
+ * quantity is "cd" (candela).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public final class LuminousIntensityAmount extends
+		BaseAmount<LuminousIntensity> implements LuminousIntensity {
+
+	public LuminousIntensityAmount(Number number, Unit<LuminousIntensity> unit) {
+		super(number, unit);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxAmount.java
new file mode 100644
index 0000000..bacd990
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.MagneticFlux;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a magnetic flux. The metric system unit for this quantity is "Wb"
+ * (Weber).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2010-05-21 $
+ */
+public class MagneticFluxAmount extends BaseAmount<MagneticFlux> implements
+		MagneticFlux {
+
+	public MagneticFluxAmount(Number number, Unit<MagneticFlux> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxDensityAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxDensityAmount.java
new file mode 100644
index 0000000..cb64a9e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagneticFluxDensityAmount.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.MagneticFluxDensity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a magnetic flux density. The metric system unit for this quantity
+ * is "T" (Tesla).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public class MagneticFluxDensityAmount extends BaseAmount<MagneticFluxDensity>
+		implements MagneticFluxDensity {
+
+	public MagneticFluxDensityAmount(Number number,
+			Unit<MagneticFluxDensity> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagnetomotiveForceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagnetomotiveForceAmount.java
new file mode 100644
index 0000000..3660eba
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MagnetomotiveForceAmount.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.MagnetomotiveForce;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents an amount of force that produces magnetic flux. The metric system
+ * unit for this quantity is "At" (ampere-turn).
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4, $Date: 2013-05-21 $
+ * @see <a href="http://en.wikipedia.org/wiki/Magnetomotive_force">Wikipedia's
+ *      Magnetomotive Force</a>
+ */
+public final class MagnetomotiveForceAmount extends
+		BaseAmount<MagnetomotiveForce> implements MagnetomotiveForce {
+
+	public MagnetomotiveForceAmount(Number number, Unit<MagnetomotiveForce> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MassAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MassAmount.java
new file mode 100644
index 0000000..f248ac3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/MassAmount.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the measure of the quantity of matter that a body or an object contains.
+ * The mass of the body is not dependent on gravity and therefore is different from but
+ * proportional to its weight.
+ * The metric system unit for this quantity is "kg" (kilogram).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.6, $Date: 2013-05-21 $
+ */
+public final class MassAmount extends BaseAmount<Mass> implements Mass {
+	
+	public MassAmount(Number number, Unit<Mass> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PowerAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PowerAmount.java
new file mode 100644
index 0000000..51c6d32
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PowerAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Power;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the rate at which work is done.
+ * The metric system unit for this quantity is "W" (Watt).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2013-05-21 $
+ */
+public final class PowerAmount extends BaseAmount<Power> implements Power {
+
+	public PowerAmount(Number number,Unit<Power> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PressureAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PressureAmount.java
new file mode 100644
index 0000000..f513d99
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/PressureAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Pressure;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a force applied uniformly over a surface.
+ * The metric system unit for this quantity is "Pa" (Pascal).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class PressureAmount extends BaseAmount<Pressure> {
+
+	public PressureAmount(Number number, Unit<Pressure> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseAmount.java
new file mode 100644
index 0000000..b2fb850
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.RadiationDoseAbsorbed;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the amount of energy deposited per unit of mass.
+ * The system unit for this quantity is "Gy" (Gray).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class RadiationDoseAmount extends BaseAmount<RadiationDoseAbsorbed> {
+
+	public RadiationDoseAmount(Number number, Unit<RadiationDoseAbsorbed> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseEffectiveAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseEffectiveAmount.java
new file mode 100644
index 0000000..f786447
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadiationDoseEffectiveAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.RadiationDoseEffective;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the effective (or "equivalent") dose of radiation
+ * received by a human or some other living organism.
+ * The metric system unit for this quantity is "Sv" (Sievert).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class RadiationDoseEffectiveAmount extends BaseAmount<RadiationDoseEffective> {
+
+	public RadiationDoseEffectiveAmount(Number number, Unit<RadiationDoseEffective> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadioactiveAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadioactiveAmount.java
new file mode 100644
index 0000000..d8bab28
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/RadioactiveAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.RadioactiveActivity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a radioactive activity.
+ * The metric system unit for this quantity is "Bq" (Becquerel).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1, $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class RadioactiveAmount extends BaseAmount<RadioactiveActivity> {
+
+	public RadioactiveAmount(Number number, Unit<RadioactiveActivity> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SolidAngleAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SolidAngleAmount.java
new file mode 100644
index 0000000..14f094b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SolidAngleAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.SolidAngle;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the angle formed by three or more planes intersecting at a common point.
+ * The metric system unit for this quantity is "sr" (steradian).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class SolidAngleAmount extends BaseAmount<SolidAngle> {
+
+	public SolidAngleAmount(Number number, Unit<SolidAngle> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SubstanceAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SubstanceAmount.java
new file mode 100644
index 0000000..ef3a9a1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/SubstanceAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.AmountOfSubstance;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the number of elementary entities (molecules, for example) of a substance.
+ * The metric system unit for this quantity is "mol" (mole).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.4 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class SubstanceAmount extends BaseAmount<AmountOfSubstance> {
+	
+	public SubstanceAmount(Number number, Unit<AmountOfSubstance> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TemperatureAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TemperatureAmount.java
new file mode 100644
index 0000000..b73e571
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TemperatureAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents the degree of hotness or coldness of a body or an environment.
+ * The metric system unit for this quantity is "K" (Kelvin).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class TemperatureAmount extends BaseAmount<Temperature> {
+
+	public TemperatureAmount(Number number, Unit<Temperature> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TimeAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TimeAmount.java
new file mode 100644
index 0000000..7acfd1f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/TimeAmount.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.AbstractConverter;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.unit.IncommensurableException;
+import org.unitsofmeasurement.unit.UnconvertibleException;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * Represents a period of existence or persistence. The metric system unit for
+ * this quantity is "s" (second).
+ * 
+ * Due to an incompatible private constructor in ICU4J TimeUnit, this uses BaseUnit.
+ * TODO add conversions with ICU4J TimeUnitAmount where necessary
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.6 ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class TimeAmount extends BaseAmount<Time> implements Time {
+
+	public TimeAmount(Number number, Unit<Time> unit) {
+		super(number, unit);
+	}
+
+	/**
+	 * Get the unit (convenience to avoid cast).
+	 * 
+	 * @draft UOMo 0.5
+	 * @provisional This API might change or be removed in a future release.
+	 */
+	public AbstractUnit<Time> unit() {
+		return (AbstractUnit<Time>) super.unit();
+	}
+
+	/**
+	 * Returns the value of this quantity as <code>double</code> stated in the
+	 * specified unit. This method is recommended over <code>
+	 * q.getUnit().getConverterTo(unit).convert(q.getNumber()).doubleValue()</code>
+	 * 
+	 * @param unit
+	 *            the unit in which the returned value is stated.
+	 * @return the value of this quantity when stated in the specified unit.
+	 */
+	public double doubleValue(Unit<Time> unit) {
+		Unit<Time> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterToAny(myUnit);
+			return converter.convert(getNumber().doubleValue());
+		} catch (UnconvertibleException e) {
+			throw e;
+		} catch (IncommensurableException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	/**
+	 * Returns the value of this quantity as <code>long</code> stated in the
+	 * specified unit. This method is recommended over <code>
+	 * q.getUnit().getConverterTo(unit).convert(q.getNumber()).longValue()</code>
+	 * 
+	 * @param unit
+	 *            the unit in which the returned value is stated.
+	 * @return the value of this quantity when stated in the specified unit.
+	 */
+	public long longValue(Unit<Time> unit) {
+		Unit<Time> myUnit = unit();
+		try {
+			UnitConverter converter = unit.getConverterToAny(myUnit);
+			return (converter.convert(
+					BigDecimal.valueOf(getNumber().longValue()),
+					MathContext.DECIMAL128)).longValue();
+		} catch (UnconvertibleException e) {
+			throw e;
+		} catch (IncommensurableException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	public TimeAmount add(IMeasure<Time> that) {
+		return new TimeAmount(super.getNumber().doubleValue()
+				+ ((BaseAmount<Time>) that).getNumber().doubleValue(),
+				that.unit());
+	}
+
+	public TimeAmount substract(IMeasure<Time> that) {
+		return new TimeAmount(super.getNumber().doubleValue()
+				- ((BaseAmount<Time>) that).getNumber().doubleValue(),
+				that.unit());
+	}
+	
+//	public IMeasure<Time> divide(IMeasure<?> that) {
+//		@SuppressWarnings("unchecked")
+//		Unit<Time> unit = (Unit<Time>) unit().divide(that.unit());
+		
+		// FIXME include number division
+//		return new TimeAmount((BigDecimal) getNumber())
+//				.divide((BigDecimal) ((Measure)that).getNumber()), unit);
+//		return new TimeAmount(getNumber(), unit);
+//	}
+
+	@SuppressWarnings({ "unchecked" })
+	public TimeAmount multiply(IMeasure<?> that) {
+		Unit<Time> unit = (Unit<Time>) unit().multiply(that.unit());
+		
+		// FIXME include number division
+//		return new TimeAmount((BigDecimal) getNumber())
+//				.divide((BigDecimal) ((Measure)that).getNumber()), unit);
+		return new TimeAmount(getNumber(), unit);
+	}
+
+	/**
+	 * Returns the amount corresponding to the specified value
+	 * and unit.
+	 * 
+	 * @param value
+	 *            the value stated in the specified unit.
+	 * @param unit
+	 *            the unit in which the value is stated.
+	 * @return the corresponding amount.
+	 */
+	public static TimeAmount valueOf(Number value, AbstractUnit<Time> unit) {
+		TimeAmount amount = new TimeAmount(value, unit);
+		return amount;
+	}
+	
+	public TimeAmount to(Unit<Time> unit) {
+		return to(unit, MathContext.DECIMAL32);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public TimeAmount to(Unit<Time> unit, MathContext ctx) {
+        if (this.unit().equals(unit))
+            return this;
+        UnitConverter cvtr = this.unit().getConverterTo(unit);
+        if (cvtr == AbstractConverter.IDENTITY)
+            return (TimeAmount) valueOf(this.getNumber(), unit);
+        return (TimeAmount) valueOf(convert(this.getNumber(), cvtr, ctx), unit);
+    }
+
+    // Try to convert the specified value.
+    private static Number convert(Number value, UnitConverter cvtr, MathContext ctx) {
+        if (cvtr instanceof RationalConverter) { // Try converting through Field methods.
+            RationalConverter rCvtr = (RationalConverter) cvtr;
+            BigInteger dividend = rCvtr.getDividend();
+            BigInteger divisor = rCvtr.getDivisor();
+            if (dividend.abs().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+                throw new ArithmeticException("Multiplier overflow");
+            if (divisor.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
+                throw new ArithmeticException("Divisor overflow");
+            return (value.longValue() * dividend.longValue()) / (divisor.longValue());
+        } else if (cvtr instanceof AbstractConverter.Compound && cvtr.isLinear()) { // Do it in two parts.
+            AbstractConverter.Compound compound = (AbstractConverter.Compound) cvtr;
+            Number firstConversion = convert(value, compound.getRight(), ctx);
+            Number secondConversion = convert(firstConversion, compound.getLeft(), ctx);
+            return secondConversion;
+        } else { // Try using BigDecimal as intermediate.
+            BigDecimal decimalValue = BigDecimal.valueOf(value.doubleValue());
+            BigDecimal newValue = cvtr.convert(decimalValue, ctx);
+            return newValue;
+//            if (((FieldNumber)value) instanceof Decimal)
+//                return (N)((FieldNumber)Decimal.valueOf(newValue));
+//            if (((FieldNumber)value) instanceof Float64)
+//                return (N)((FieldNumber)Float64.valueOf(newValue.doubleValue()));
+//            throw new ArithmeticException(
+//                    "Generic amount conversion not implemented for amount of type " + value.getClass());
+        }
+    }
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VelocityAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VelocityAmount.java
new file mode 100644
index 0000000..ff91aa0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VelocityAmount.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Velocity;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * Represents a distance traveled divided by the time of travel.
+ * The metric system unit for this quantity is "m/s" (metre per second).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.2, ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class VelocityAmount extends BaseAmount<Velocity> {
+
+	public VelocityAmount(Number number, Unit<Velocity> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VolumeAmount.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VolumeAmount.java
new file mode 100644
index 0000000..a8a0d0a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/VolumeAmount.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Volume;
+import org.unitsofmeasurement.unit.Unit;
+
+
+/**
+ * Represents the amount of space occupied by a three-dimensional object or region of space.
+ * The metric system unit for this quantity is "m³" (cubic metre).
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.3, ($Revision: 212 $), $Date: 2010-09-13 23:50:44 +0200 (Mo, 13 Sep 2010) $
+ */
+public class VolumeAmount extends BaseAmount<Volume> {
+
+	public VolumeAmount(Number number, Unit<Volume> unit) {
+		super(number, unit);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/package-info.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/package-info.java
new file mode 100644
index 0000000..34d33a3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/quantity/package-info.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/**
+ * Provides quantitative properties or attributes of thing such as
+ * mass, time, distance, heat, and angular separation.
+ * Quantities of different kinds are represented by sub-types of the
+ * {@link org.unitsofmeasurement.quantity.Quantity} interface, which can be
+ * created by a new {@link org.eclipse.uomo.units.impl.BaseAmount} instance or its subclasses.
+ *
+ * <p> Only quantities defined in the <a href="http://en.wikipedia.org/wiki/International_System_of_Units">International System of Units</a>
+ *     are provided here. Users can create their own quantity types by extending the {@link
+ *     org.unitsofmeasurement.quantity.Quantity Quantity} interface.</p>
+ *
+ * <p> This package supports <cite>measurable</cite> quantities, which can be
+ *     expressed as ({@link java.lang.Number}, {@link org.unitsofmeasurement.unit.Unit}) tuples.
+ *     Those tuples are not expected to be used directly in numerically intensive code.
+ *     They are more useful as metadata converted to the application internal representation
+ *     (for example {@code double} primitive type with the requirement to provide values in
+ *     metres) before the computation begin. For this purpose, the {@code Quantity} interface
+ *     provides the {@code longValue(Unit<Q>)} and {@code doubleValue(Unit<Q>)} convenience
+ *     methods. Example:[code]
+ *        TimeAmount calculateTravelTime(Length distance, Velocity velocity) {
+ *            double seconds = distance.doubleValue(METRE) /
+ *                             velocity.doubleValue(METRE_PER_SECOND);
+ *            return new TimeAmount(seconds, SECOND);
+ *        }
+ *     [/code]
+ * </p>
+ *
+ * <p> Quantities sub-types are also used as parameterized type to characterize generic
+ *     classes (and provide additional compile time check) as illustrated here.[code]
+ *        Sensor<Temperature> sensor ... // Generic sensor.
+ *        Temperature temp = sensor.getValue();
+ *        MassAmount mass = new MassAmount(180, POUND); // Combination magnitude/precision/unit (measurement)
+ *        Vector3D<Velocity> aircraftSpeed = new Vector3D(12.0, 34.0, -45.5, METRE_PER_SECOND);
+ *     [/code]</p>
+ *
+ * <p> This package holds only the quantities required by the metric system.</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 2.2, $Date: 2011-01-09 19:56:23 +0100 (So, 09 Jan 2011) $
+ */
+package org.eclipse.uomo.units.impl.quantity;
+
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/CommonUnits.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/CommonUnits.java
new file mode 100644
index 0000000..6cb5e7e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/CommonUnits.java
@@ -0,0 +1,38 @@
+package org.eclipse.uomo.units.impl.system;
+
+import static org.eclipse.uomo.units.SI.METRES_PER_SECOND;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.unitsofmeasurement.quantity.Velocity;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+public class CommonUnits extends AbstractSystemOfUnits {
+
+	private CommonUnits() {
+		
+	}
+	
+	private static final CommonUnits INSTANCE = new CommonUnits();
+	
+	public String getName() {
+		return "Common Units";
+	}
+
+	/**
+	 * A unit of velocity expressing the number of international {@link #KILOMETRE
+	 * kilometres} per {@link #HOUR hour} (abbreviation <code>kph</code>).
+	 */
+	public static final Unit<Velocity> KILOMETRES_PER_HOUR = addUnit(
+			METRES_PER_SECOND.multiply(0.277778d)).asType(Velocity.class);
+	
+	/**
+	 * Returns the unique instance of this class.
+	 * 
+	 * @return the Imperial instance.
+	 */
+	public static SystemOfUnits getInstance() {
+		return INSTANCE;
+	}
+	
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/Imperial.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/Imperial.java
new file mode 100644
index 0000000..af6db53
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/Imperial.java
@@ -0,0 +1,254 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.system;
+
+
+import static org.eclipse.uomo.units.SI.*;
+import static org.eclipse.uomo.units.SI.Prefix.MICRO;
+import static org.eclipse.uomo.units.internal.NonSI.AVOIRDUPOIS_POUND_DIVIDEND;
+import static org.eclipse.uomo.units.internal.NonSI.AVOIRDUPOIS_POUND_DIVISOR;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.unitsofmeasurement.quantity.Area;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.quantity.Volume;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p>
+ * This class contains units from the Imperial system.
+ * </p>
+ * <p>
+ * 
+ * @noextend This class is not intended to be extended by clients.
+ * 
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.1 ($Revision: 332 $), $Date: 2011-09-11 14:52:11 +0200 $
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/http://en.wikipedia.org/wiki/Imperial_unit">Wikipedia:
+ *      Imperial Units</a>
+ */
+public final class Imperial extends AbstractSystemOfUnits  {
+
+	/**
+	 * Default constructor (prevents this class from being instantiated).
+	 */
+	private Imperial() {
+	}
+
+	/**
+	 * Returns the unique instance of this class.
+	 * 
+	 * @return the Imperial instance.
+	 */
+	public static SystemOfUnits getInstance() {
+		return INSTANCE;
+	}
+
+	private static final Imperial INSTANCE = new Imperial();
+
+	// //////////
+	// Length //
+	// //////////
+
+	/**
+	 * A unit of length equal to <code>0.0254 m</code> (standard name
+	 * <code>in</code>).
+	 */
+	public static final Unit<Length> INCH = USCustomary.INCH;
+	
+	// ////////
+	// Mass //
+	// ////////
+
+	/**
+	 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
+	 * standard name <code>lb</code>).
+	 */
+	static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(
+			AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR));
+
+	/**
+	 * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name
+	 * <code>oz</code>).
+	 */
+	public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16));
+	
+	/**
+	 * A unit of mass equal to <code>2240 {@link #POUND}</code> (long ton,
+	 * standard name <code>ton_uk</code>).
+	 */
+	public static final Unit<Mass> TON_UK = addUnit(POUND.multiply(2240));
+
+	/**
+	 * A unit of mass equal to <code>1000 kg</code> (metric ton, standard name
+	 * <code>t</code>).
+	 */
+	public static final Unit<Mass> METRIC_TON = addUnit(KILOGRAM.multiply(1000));
+
+	// ///////////////
+	// Temperature //
+	// ///////////////
+
+	/**
+	 * A unit of temperature equal to <code>5/9 °K</code> (standard name
+	 * <code>°R</code>).
+	 */
+	static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5)
+			.divide(9));
+
+	/**
+	 * A unit of temperature equal to degree Rankine minus
+	 * <code>459.67 °R</code> (standard name <code>°F</code>).
+	 * 
+	 * @see #RANKINE
+	 */
+	static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE
+			.add(459.67));
+
+	// /////////
+	// Angle //
+	// /////////
+
+	
+	// ////////////
+	// TimeUnit //
+	// ////////////
+	/**
+	 * A unit of time equal to <code>60 s</code> (standard name <code>min</code>
+	 * ).
+	 */
+	static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
+
+	/**
+	 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
+	 * name <code>h</code>).
+	 */
+	static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
+
+	// ////////////
+	// Velocity //
+	// ////////////
+
+
+	// ////////
+	// Area //
+	// ////////
+
+	/**
+	 * A unit of area (standard name <code>sft</code>
+	 * ).
+	 */
+	public static final Unit<Area> SQUARE_FOOT = USCustomary.SQUARE_FOOT;
+	
+	/**
+	 * One acre is 43,560 <code>square feet</code> (standard name <code>a</code>
+	 * ).
+	 */
+	public static final Unit<Area> ACRE = addUnit(SQUARE_FOOT.multiply(43560));
+
+	// ///////////////
+	// Data Amount //
+	// ///////////////
+	
+
+	// //////////
+	// Energy //
+	// //////////
+
+
+	// //////////
+	// Volume //
+	// //////////
+	/**
+	 * A unit of volume equal to one cubic decimeter (default label
+	 * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>).
+	 */
+	static final Unit<Volume> LITRE = addUnit(CUBIC_METRE.divide(1000));
+
+	/**
+	 * A unit of volume equal to one cubic inch (<code>in³</code>).
+	 */
+	static final Unit<Volume> CUBIC_INCH = addUnit(INCH.pow(3).asType(
+			Volume.class));
+
+	/**
+	 * A unit of volume equal to <code>4.546 09 {@link #LITRE}</code> (standard
+	 * name <code>gal_uk</code>).
+	 */
+	public static final Unit<Volume> GALLON_UK = addUnit(LITRE.multiply(454609)
+			.divide(100000));
+
+	/**
+	 * A unit of volume equal to one UK gallon, Liquid Unit.
+	 */
+	public static final Unit<Volume> GALLON_LIQUID = addUnit(CUBIC_INCH
+			.multiply(277.42));
+	
+	/**
+	 * A unit of volume equal to <code>1 / 160 {@link #GALLON_UK}</code>
+	 * (standard name <code>oz_fl_uk</code>).
+	 */
+	static final Unit<Volume> OUNCE_LIQUID_UK = addUnit(GALLON_UK
+			.divide(160));
+	
+	/**
+	 * A unit of volume equal to <code>1 / 160 {@link #GALLON_LIQUID}</code>
+	 * (standard name <code>oz_fl</code>).
+	 */
+	public static final Unit<Volume> OUNCE_LIQUID = OUNCE_LIQUID_UK;
+
+	/**
+	 * A unit of volume equal to <code>5 {@link #OUNCE_LIQUID}</code> (standard name
+	 * <code>gi</code>).
+	 */
+	public static final Unit<Volume> GILL = addUnit(OUNCE_LIQUID.multiply(5));
+
+	/**
+	 * A unit of volume equal to <code>20 {@link #OUNCE_LIQUID}</code> (standard name
+	 * <code>pt</code>).
+	 */
+	public static final Unit<Volume> PINT = addUnit(OUNCE_LIQUID.multiply(20));
+
+	/**
+	 * A unit of volume equal to <code>40 {@link #OUNCE_LIQUID}</code> (standard name
+	 * <code>qt</code>).
+	 */
+	public static final Unit<Volume> QUART = addUnit(OUNCE_LIQUID.multiply(40));
+	
+	/**
+	 * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard
+	 * name <code>min</code>).
+	 */
+	public static final Unit<Volume> MINIM = addUnit(MICRO(LITRE).multiply(
+			59.1938802d));
+
+	/**
+	 * A unit of volume equal to <code>20 {@link #MINIM}</code> (standard name
+	 * <code>fl scr</code>).
+	 */
+	public static final Unit<Volume> FLUID_SCRUPLE = addUnit(MINIM.multiply(60));
+
+	/**
+	 * A unit of volume equal to <code>3 {@link #FLUID_SCRUPLE}</code> (standard name
+	 * <code>fl drc</code>).
+	 */
+	public static final Unit<Volume> FLUID_DRACHM = addUnit(FLUID_SCRUPLE.multiply(3));
+
+
+	public String getName() {
+		return getClass().getSimpleName();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/SystemOfUnitsServiceImpl.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/SystemOfUnitsServiceImpl.java
new file mode 100644
index 0000000..c78c194
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/SystemOfUnitsServiceImpl.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.system;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.service.SystemOfUnitsService;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+
+/**
+ * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 0.6.1, $Date$
+ */
+public class SystemOfUnitsServiceImpl implements SystemOfUnitsService {
+	
+	final Map<String, SystemOfUnits> souMap = new HashMap<String, SystemOfUnits>();
+
+	public SystemOfUnitsServiceImpl() {
+		souMap.put(SI.class.getSimpleName(), SI.getInstance());
+		souMap.put(CommonUnits.class.getSimpleName(), CommonUnits.getInstance());
+		souMap.put(USCustomary.class.getSimpleName(), USCustomary.getInstance());
+	}
+	
+	public Collection<SystemOfUnits> getSystemsOfUnits() {
+		return souMap.values();
+	}
+	
+	@Override
+	public SystemOfUnits getSystemOfUnits() {
+		return getSystemOfUnits(SI.class.getSimpleName());
+	}
+
+	@Override
+	public SystemOfUnits getSystemOfUnits(String name) {
+		return souMap.get(name);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/USCustomary.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/USCustomary.java
new file mode 100644
index 0000000..a5eba34
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/impl/system/USCustomary.java
@@ -0,0 +1,393 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+package org.eclipse.uomo.units.impl.system;
+
+import static org.eclipse.uomo.units.SI.*;
+import static org.eclipse.uomo.units.SI.Prefix.MICRO;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.Messages;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.ProductUnit;
+import org.unitsofmeasurement.quantity.Angle;
+import org.unitsofmeasurement.quantity.Area;
+import org.unitsofmeasurement.quantity.Information;
+import org.unitsofmeasurement.quantity.Energy;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.quantity.Power;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.quantity.Velocity;
+import org.unitsofmeasurement.quantity.Volume;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p>
+ * This class contains units from the United States customary system.
+ * </p>
+ * <p>
+ * 
+ * @noextend This class is not intended to be extended by clients.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 1.15 ($Revision: 332 $), $Date: 2011-09-11 14:52:11 +0200 $
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/United_States_customary_units">Wikipedia:
+ *      United State Customary Units</a>
+ */
+public final class USCustomary extends AbstractSystemOfUnits {
+
+	/**
+	 * Default constructor (prevents this class from being instantiated).
+	 */
+	private USCustomary() {
+	}
+
+	/**
+	 * Returns the unique instance of this class.
+	 * 
+	 * @return the USCustomary instance.
+	 */
+	public static SystemOfUnits getInstance() {
+		return INSTANCE;
+	}
+
+	private static final USCustomary INSTANCE = new USCustomary();
+
+	// //////////
+	// Length //
+	// //////////
+	/**
+	 * US name for {@link SI#METRE}.
+	 */
+	public static final Unit<Length> METER = METRE;
+
+	/**
+	 * A unit of length equal to <code>0.3048 m</code> (standard name
+	 * <code>ft</code>).
+	 */
+	public static final Unit<Length> FOOT = addUnit(METER.multiply(3048)
+			.divide(10000));
+
+	/**
+	 * A unit of length equal to <code>1200/3937 m</code> (standard name
+	 * <code>foot_survey_us</code>). See also: <a
+	 * href="http://www.sizes.com/units/foot.htm">foot</a>
+	 */
+	public static final Unit<Length> FOOT_SURVEY = addUnit(METER.multiply(1200)
+			.divide(3937));
+
+	/**
+	 * A unit of length equal to <code>0.9144 m</code> (standard name
+	 * <code>yd</code>).
+	 */
+	public static final Unit<Length> YARD = addUnit(FOOT.multiply(3));
+
+	/**
+	 * A unit of length equal to <code>0.0254 m</code> (standard name
+	 * <code>in</code>).
+	 */
+	public static final Unit<Length> INCH = addUnit(FOOT.divide(12));
+
+	/**
+	 * A unit of length equal to <code>1609.344 m</code> (standard name
+	 * <code>mi</code>).
+	 */
+	public static final Unit<Length> MILE = addUnit(METER.multiply(1609344)
+			.divide(1000));
+
+	/**
+	 * A unit of length equal to the distance that light travels in one year
+	 * through a vacuum (standard name <code>ly</code>).
+	 */
+	public static final Unit<Length> LIGHT_YEAR = addUnit(METRE
+			.multiply(9.460528405e15));
+	
+	/**
+	 * A unit of length equal to <code>1852.0 m</code> (standard name
+	 * <code>nmi</code>).
+	 */
+	public static final Unit<Length> NAUTICAL_MILE = addUnit(METER
+			.multiply(1852));
+
+	// ////////
+	// Mass //
+	// ////////
+
+	/**
+	 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
+	 * standard name <code>lb</code>).
+	 */
+	public static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(45359237)
+			.divide(100000000), Messages.US_lb_name);
+
+	/**
+	 * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name
+	 * <code>oz</code>).
+	 */
+	public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16));
+
+	/**
+	 * A unit of mass equal to <code>2000 {@link #POUND}</code> (short ton,
+	 * standard name <code>ton</code>).
+	 */
+	public static final Unit<Mass> TON = addUnit(POUND.multiply(2000));
+
+	// ///////////////
+	// Temperature //
+	// ///////////////
+
+	/**
+	 * A unit of temperature equal to <code>5/9 °K</code> (standard name
+	 * <code>°R</code>).
+	 */
+	public static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5)
+			.divide(9));
+
+	/**
+	 * A unit of temperature equal to degree Rankine minus
+	 * <code>459.67 °R</code> (standard name <code>°F</code>).
+	 * 
+	 * @see #RANKINE
+	 */
+	public static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE
+			.add(459.67));
+
+	// /////////
+	// Angle //
+	// /////////
+
+	/**
+	 * A unit of angle equal to a full circle or <code>2<i>&pi;</i>
+	 * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
+	 */
+	public static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2)
+			.multiply(Math.PI).asType(Angle.class));
+
+	/**
+	 * A unit of angle equal to <code>1/360 {@link #REVOLUTION}</code> (standard
+	 * name <code>deg</code>).
+	 */
+	public static final Unit<Angle> DEGREE_ANGLE = addUnit(REVOLUTION
+			.divide(360));
+
+	/**
+	 * A unit of angle equal to <code>1/60 {@link #DEGREE_ANGLE}</code>
+	 * (standard name <code>'</code>).
+	 */
+	public static final Unit<Angle> MINUTE_ANGLE = addUnit(DEGREE_ANGLE
+			.divide(60));
+
+	/**
+	 * A unit of angle equal to <code>1/60 {@link #MINUTE_ANGLE}</code>
+	 * (standard name <code>"</code>).
+	 */
+	public static final Unit<Angle> SECOND_ANGLE = addUnit(MINUTE_ANGLE
+			.divide(60));
+
+	/**
+	 * A unit of angle equal to <code>0.01 {@link SI#RADIAN}</code> (standard
+	 * name <code>centiradian</code>).
+	 */
+	public static final Unit<Angle> CENTIRADIAN = addUnit(RADIAN.divide(100));
+
+	/**
+	 * A unit of angle measure equal to <code>1/400 {@link #REVOLUTION}</code>
+	 * (standard name <code>grade</code> ).
+	 */
+	public static final Unit<Angle> GRADE = addUnit(REVOLUTION.divide(400));
+	
+	// ////////////
+	// TimeUnit //
+	// ////////////
+	/**
+	 * A unit of time equal to <code>60 s</code> (standard name <code>min</code>
+	 * ).
+	 */
+	public static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
+
+	/**
+	 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
+	 * name <code>h</code>).
+	 */
+	public static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
+
+	// ////////////
+	// Velocity //
+	// ////////////
+	/**
+	 * A unit of velocity expressing the number of {@link #FOOT feet} per
+	 * {@link SI#SECOND second}.
+	 */
+	public static final Unit<Velocity> FEET_PER_SECOND = addUnit(
+			FOOT.divide(SECOND)).asType(Velocity.class);
+
+	/**
+	 * A unit of velocity expressing the number of international {@link #MILE
+	 * miles} per {@link #HOUR hour} (abbreviation <code>mph</code>).
+	 */
+	public static final Unit<Velocity> MILES_PER_HOUR = addUnit(
+			MILE.divide(HOUR)).asType(Velocity.class);
+
+	/**
+	 * A unit of velocity expressing the number of {@link #NAUTICAL_MILE
+	 * nautical miles} per {@link #HOUR hour} (abbreviation <code>kn</code>).
+	 */
+	public static final Unit<Velocity> KNOT = addUnit(
+			NAUTICAL_MILE.divide(HOUR)).asType(Velocity.class);
+
+	// ////////
+	// Area //
+	// ////////
+
+	/**
+	 * A unit of area (standard name <code>sft</code>
+	 * ).
+	 */
+	public static final Unit<Area> SQUARE_FOOT = addUnit(new ProductUnit<Area>(
+			(AbstractUnit<?>) FOOT.multiply(FOOT)));
+
+	/**
+	 * A unit of area equal to <code>100 m²</code> (standard name <code>a</code>
+	 * ).
+	 */
+	public static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100));
+	
+	/**
+	 * A unit of area equal to <code>100 {@link #ARE}</code> (standard name
+	 * <code>ha</code>).
+	 */
+	static final Unit<Area> HECTARE = addUnit(ARE.multiply(100)); // Exact.
+	
+	// ///////////////
+	// Data Amount //
+	// ///////////////
+	/**
+	 * A unit of data amount equal to <code>8 {@link SI#BIT}</code> (BinarY
+	 * TErm, standard name <code>byte</code>).
+	 */
+	public static final Unit<Information> BYTE = addUnit(BIT.multiply(8));
+
+	/**
+	 * Equivalent {@link #BYTE}
+	 */
+	public static final Unit<Information> OCTET = BYTE;
+
+	// //////////
+	// Energy //
+	// //////////
+
+	/**
+	 * A unit of energy equal to one electron-volt (standard name
+	 * <code>eV</code>, also recognized <code>keV, MeV, GeV</code>).
+	 */
+	public static final Unit<Energy> ELECTRON_VOLT = addUnit(JOULE
+			.multiply(1.602176462e-19));
+	
+	// //////////
+	// Power   //
+	// //////////
+	
+	/**
+	 * Horsepower (HP) is the name of several units of measurement of power.
+	 * The most common definitions equal between 735.5 and 750 watts.
+	 * Horsepower was originally defined to compare the output of steam engines with the power of draft horses. 
+	 * The unit was widely adopted to measure the output of piston engines, turbines, electric motors, and other machinery. The definition of the unit varied between geographical regions. Most countries now use the SI unit watt for measurement of power. With the implementation of the EU Directive 80/181/EEC on January 1, 2010, the use of horsepower in the EU is only permitted as supplementary unit.
+	 */
+	public static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(735.499));
+
+	// //////////
+	// Volume //
+	// //////////
+	/**
+	 * A unit of volume equal to one cubic decimeter (default label
+	 * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>).
+	 */
+	public static final Unit<Volume> LITER = addUnit(CUBIC_METRE.divide(1000));
+
+	/**
+	 * A unit of volume equal to one cubic inch (<code>in³</code>).
+	 */
+	public static final Unit<Volume> CUBIC_INCH = addUnit(INCH.pow(3).asType(
+			Volume.class));
+
+	/**
+	 * A unit of volume equal to one US dry gallon. (standard name
+	 * <code>gallon_dry_us</code>).
+	 */
+	public static final Unit<Volume> GALLON_DRY = addUnit(CUBIC_INCH.multiply(
+			2688025).divide(10000));
+
+	/**
+	 * A unit of volume equal to one US gallon, Liquid Unit. The U.S. liquid
+	 * gallon is based on the Queen Anne or Wine gallon occupying 231 cubic
+	 * inches (standard name <code>gal</code>).
+	 */
+	public static final Unit<Volume> GALLON_LIQUID = addUnit(CUBIC_INCH
+			.multiply(231));
+
+	/**
+	 * A unit of volume equal to <code>1 / 128 {@link #GALLON_LIQUID}</code>
+	 * (standard name <code>oz_fl</code>).
+	 */
+	public static final Unit<Volume> OUNCE_LIQUID = addUnit(GALLON_LIQUID
+			.divide(128));
+
+	/**
+	 * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard
+	 * name <code>min</code>).
+	 */
+	public static final Unit<Volume> MINIM = addUnit(MICRO(LITER).multiply(
+			61.61152d));
+
+	/**
+	 * A unit of volume equal to <code>60 {@link #MINIM}</code> (standard name
+	 * <code>fl dr</code>).
+	 */
+	public static final Unit<Volume> FLUID_DRAM = addUnit(MINIM.multiply(60));
+
+	/**
+	 * A unit of volume equal to <code>80 {@link #MINIM}</code> (standard name
+	 * <code>tsp</code>).
+	 */
+	public static final Unit<Volume> TEASPOON = addUnit(MINIM.multiply(80));
+
+	/**
+	 * A unit of volume equal to <code>3 {@link #TEASPOON}</code> (standard name
+	 * <code>Tbsp</code>).
+	 */
+	public static final Unit<Volume> TABLESPOON = addUnit(TEASPOON.multiply(3));
+
+	/**
+	 * A unit of volume equal to <code>238.4810 {@link #LITER}</code> (standard
+	 * name <code>bbl</code>).
+	 */
+	public static final Unit<Volume> OIL_BARREL = addUnit(LITER
+			.multiply(238.4810d));
+
+	/**
+	 * Holds the international foot: 0.3048 m exact.
+	 */
+	// private static final int INTERNATIONAL_FOOT_DIVIDEND = 3048;
+
+	// private static final int INTERNATIONAL_FOOT_DIViSOR = 10000;
+
+
+
+	@Override
+	public String getName() {
+		return getClass().getSimpleName();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/internal/NonSI.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/internal/NonSI.java
new file mode 100644
index 0000000..0fa5a18
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/internal/NonSI.java
@@ -0,0 +1,602 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Jean-Marie Dautelle - initial API and implementation
+ */
+package org.eclipse.uomo.units.internal;
+
+import static org.eclipse.uomo.units.SI.AMPERE;
+import static org.eclipse.uomo.units.SI.BECQUEREL;
+import static org.eclipse.uomo.units.SI.BIT;
+import static org.eclipse.uomo.units.SI.COULOMB;
+import static org.eclipse.uomo.units.SI.GRAM;
+import static org.eclipse.uomo.units.SI.GRAY;
+import static org.eclipse.uomo.units.SI.JOULE;
+import static org.eclipse.uomo.units.SI.KELVIN;
+import static org.eclipse.uomo.units.SI.KILOGRAM;
+import static org.eclipse.uomo.units.SI.LUX;
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.METRES_PER_SECOND;
+import static org.eclipse.uomo.units.SI.METRES_PER_SQUARE_SECOND;
+import static org.eclipse.uomo.units.SI.MOLE;
+import static org.eclipse.uomo.units.SI.NEWTON;
+import static org.eclipse.uomo.units.SI.PASCAL;
+import static org.eclipse.uomo.units.SI.RADIAN;
+import static org.eclipse.uomo.units.SI.SECOND;
+import static org.eclipse.uomo.units.SI.SIEVERT;
+import static org.eclipse.uomo.units.SI.SQUARE_METRE;
+import static org.eclipse.uomo.units.SI.STERADIAN;
+import static org.eclipse.uomo.units.SI.TESLA;
+import static org.eclipse.uomo.units.SI.WATT;
+import static org.eclipse.uomo.units.SI.WEBER;
+import static org.eclipse.uomo.units.SI.Prefix.*;
+
+import java.math.BigInteger;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.eclipse.uomo.units.AbstractUnit;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.converter.LogConverter;
+import org.eclipse.uomo.units.impl.converter.RationalConverter;
+import org.unitsofmeasurement.quantity.*;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * <p>
+ * This class contains units that are not part of the International System of
+ * Units, that is, they are outside the SI, but are important and widely used.
+ * </p>
+ * 
+ * <p>
+ * This is an internal collection of otherwise unassigned units used by
+ * <b>UCUM</b> or similar systems.
+ * </p>
+ * <p>
+ * This class is not intended to be implemented by clients.
+ * </p>
+ * 
+ * @noimplement This class is not intended to be implemented by clients.
+ * @noextend This class is not intended to be extended by clients.
+ * 
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
+ * @version 1.17 ($Revision: 231 $), $Date: 2011-09-11 14:57:59 +0200 (So, 11 Sep
+ *          2011) $
+ */
+public final class NonSI extends AbstractSystemOfUnits {
+
+	/**
+	 * Holds the standard gravity constant: 9.80665 m/s² exact.
+	 */
+	private static final int STANDARD_GRAVITY_DIVIDEND = 980665;
+
+	private static final int STANDARD_GRAVITY_DIVISOR = 100000;
+
+	/**
+	 * Holds the avoirdupois pound: 0.45359237 kg exact
+	 */
+	public static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
+
+	public static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
+
+	/**
+	 * Holds the Avogadro constant.
+	 */
+	private static final double AVOGADRO_CONSTANT = 6.02214199e23; // (1/mol).
+
+	/**
+	 * Holds the electric charge of one electron.
+	 */
+	private static final double ELEMENTARY_CHARGE = 1.602176462e-19; // (C).
+
+	/**
+	 * Default constructor (prevents this class from being instantiated).
+	 */
+	private NonSI() {
+	}
+
+	/**
+	 * Returns the unique instance of this class.
+	 * 
+	 * @return the NonSI instance.
+	 */
+	static NonSI getInstance() {
+		return INSTANCE;
+	}
+
+	private static final NonSI INSTANCE = new NonSI();
+
+	// /////////////////
+	// Dimensionless //
+	// /////////////////
+	/**
+	 * A dimensionless unit equals to <code>pi</code> (standard name
+	 * <code>Ï€</code>).
+	 */
+	static final Unit<Dimensionless> PI = addUnit(AbstractUnit.ONE
+			.multiply(StrictMath.PI));
+
+	/**
+	 * A dimensionless unit equals to <code>0.01</code> (standard name
+	 * <code>%</code>).
+	 */
+	static final Unit<Dimensionless> PERCENT = addUnit(AbstractUnit.ONE
+			.divide(100));
+
+	/**
+	 * A logarithmic unit used to describe a ratio (standard name
+	 * <code>dB</code>).
+	 */
+	static final Unit<Dimensionless> DECIBEL = addUnit(AbstractUnit.ONE
+			.transform(new LogConverter(10).inverse().concatenate(
+					new RationalConverter(BigInteger.ONE, BigInteger.TEN))));
+
+	// ///////////////////////
+	// Amount of substance //
+	// ///////////////////////
+	/**
+	 * A unit of amount of substance equals to one atom (standard name
+	 * <code>atom</code>).
+	 */
+	static final Unit<AmountOfSubstance> ATOM = addUnit(MOLE
+			.divide(AVOGADRO_CONSTANT));
+
+	// //////////
+	// Length //
+	// //////////
+
+	/**
+	 * A unit of length equal to <code>0.3048 m</code> (standard name
+	 * <code>ft</code>).
+	 */
+	static final Unit<Length> FOOT = addUnit(METRE.multiply(3048)
+			.divide(10000));
+	
+	/**
+	 * A unit of length equal to <code>0.0254 m</code> (standard name
+	 * <code>in</code>).
+	 */
+	static final Unit<Length> INCH = addUnit(FOOT.divide(12));
+	
+	/**
+	 * A unit of length equal to <code>1E-10 m</code> (standard name
+	 * <code>\u00C5ngstr\u00F6m</code>).
+	 */
+	static final Unit<Length> ANGSTROM = addUnit(METRE
+			.divide(10000000000L));
+
+	/**
+	 * A unit of length equal to the average distance from the center of the
+	 * Earth to the center of the Sun (standard name <code>ua</code>).
+	 */
+	static final Unit<Length> ASTRONOMICAL_UNIT = addUnit(METRE
+			.multiply(149597870691.0));
+
+	/**
+	 * A unit of length equal to the distance that light travels in one year
+	 * through a vacuum (standard name <code>ly</code>).
+	 */
+	static final Unit<Length> LIGHT_YEAR = addUnit(METRE
+			.multiply(9.460528405e15));
+
+	/**
+	 * A unit of length equal to the distance at which a star would appear to
+	 * shift its position by one arcsecond over the course the time (about 3
+	 * months) in which the Earth moves a distance of {@link #ASTRONOMICAL_UNIT}
+	 * in the direction perpendicular to the direction to the star (standard
+	 * name <code>pc</code>).
+	 */
+	static final Unit<Length> PARSEC = addUnit(METRE
+			.multiply(30856770e9));
+
+	/**
+	 * A unit of length equal to <code>0.013837 {@link #INCH}</code> exactly
+	 * (standard name <code>pt</code>).
+	 * 
+	 * @see #PIXEL
+	 */
+	static final Unit<Length> POINT = addUnit(INCH.multiply(13837)
+			.divide(1000000));
+
+	/**
+	 * A unit of length equal to <code>1/72 {@link #INCH}</code> (standard name
+	 * <code>pixel</code>). It is the American point rounded to an even 1/72
+	 * inch.
+	 * 
+	 * @see #POINT
+	 */
+	static final Unit<Length> PIXEL = addUnit(INCH.divide(72));
+
+	/**
+	 * Equivalent {@link #PIXEL}
+	 */
+	static final Unit<Length> COMPUTER_POINT = PIXEL;
+
+	// ////////////
+	// Duration //
+	// ////////////
+	/**
+	 * A unit of duration equal to <code>60 s</code> (standard name
+	 * <code>min</code>).
+	 */
+	static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
+
+	/**
+	 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
+	 * name <code>h</code>).
+	 */
+	static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
+
+	/**
+	 * A unit of duration equal to <code>24 {@link #HOUR}</code> (standard name
+	 * <code>d</code>).
+	 */
+	static final Unit<Time> DAY = addUnit(HOUR.multiply(24));
+
+	/**
+	 * A unit of duration equal to the time required for a complete rotation of
+	 * the earth in reference to any star or to the vernal equinox at the
+	 * meridian, equal to 23 hours, 56 minutes, 4.09 seconds (standard name
+	 * <code>day_sidereal</code>).
+	 */
+	static final Unit<Time> DAY_SIDEREAL = addUnit(SECOND
+			.multiply(86164.09));
+
+	/**
+	 * A unit of duration equal to 7 {@link #DAY} (standard name
+	 * <code>week</code>).
+	 */
+	static final Unit<Time> WEEK = addUnit(DAY.multiply(7));
+
+	/**
+	 * A unit of duration equal to 365 {@link #DAY} (standard name
+	 * <code>year</code>).
+	 */
+	static final Unit<Time> YEAR_CALENDAR = addUnit(DAY.multiply(365));
+
+	/**
+	 * A unit of duration equal to one complete revolution of the earth about
+	 * the sun, relative to the fixed stars, or 365 days, 6 hours, 9 minutes,
+	 * 9.54 seconds (standard name <code>year_sidereal</code>).
+	 */
+	static final Unit<Time> YEAR_SIDEREAL = addUnit(SECOND
+			.multiply(31558149.54));
+
+	/**
+	 * The Julian year, as used in astronomy and other sciences, is a time unit
+	 * defined as exactly 365.25 days. This is the normal meaning of the unit
+	 * "year" (symbol "a" from the Latin annus, annata) used in various
+	 * scientific contexts.
+	 */
+	static final Unit<Time> YEAR_JULIEN = addUnit(SECOND
+			.multiply(31557600));
+
+	// ////////
+	// Mass //
+	// ////////
+	/**
+	 * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
+	 * name <code>u</code>).
+	 */
+	static final Unit<Mass> ATOMIC_MASS = addUnit(KILOGRAM
+			.multiply(1e-3 / AVOGADRO_CONSTANT));
+
+	/**
+	 * A unit of mass equal to the mass of the electron (standard name
+	 * <code>me</code>).
+	 */
+	static final Unit<Mass> ELECTRON_MASS = addUnit(KILOGRAM
+			.multiply(9.10938188e-31));
+
+	/**
+	 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
+	 * standard name <code>lb</code>).
+	 */
+	static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(
+			AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR));
+
+	// ///////////////////
+	// Electric charge //
+	// ///////////////////
+	/**
+	 * A unit of electric charge equal to the charge on one electron (standard
+	 * name <code>e</code>).
+	 */
+	static final Unit<ElectricCharge> E = addUnit(COULOMB
+			.multiply(ELEMENTARY_CHARGE));
+
+	/**
+	 * A unit of electric charge equal to equal to the product of Avogadro's
+	 * number (see {@link SI#MOLE}) and the charge (1 e) on a single electron
+	 * (standard name <code>Fd</code>).
+	 */
+	static final Unit<ElectricCharge> FARADAY = addUnit(COULOMB
+			.multiply(ELEMENTARY_CHARGE * AVOGADRO_CONSTANT)); // e/mol
+
+	/**
+	 * A unit of electric charge which exerts a force of one dyne on an equal
+	 * charge at a distance of one centimeter (standard name <code>Fr</code>).
+	 */
+	static final Unit<ElectricCharge> FRANKLIN = addUnit(COULOMB
+			.multiply(3.3356e-10));
+
+	// ///////////////
+	// Temperature //
+	// ///////////////
+	/**
+	 * A unit of temperature equal to <code>5/9 °K</code> (standard name
+	 * <code>°R</code>).
+	 */
+	static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5)
+			.divide(9));
+
+	// /////////
+	// Angle //
+	// /////////
+
+	/**
+	 * A unit of angle equal to a full circle or <code>2<i>&pi;</i>
+	 * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
+	 */
+	static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2)
+			.multiply(Math.PI).asType(Angle.class));
+	
+	// ////////////
+	// Velocity //
+	// ////////////
+	/**
+	 * A unit of velocity relative to the speed of light (standard name
+	 * <code>c</code>).
+	 */
+	static final Unit<Velocity> C = addUnit(METRES_PER_SECOND
+			.multiply(299792458));
+
+	// ////////////////
+	// Acceleration //
+	// ////////////////
+	/**
+	 * A unit of acceleration equal to the gravity at the earth's surface
+	 * (standard name <code>grav</code>).
+	 */
+	static final Unit<Acceleration> G = addUnit(METRES_PER_SQUARE_SECOND
+			.multiply(STANDARD_GRAVITY_DIVIDEND).divide(
+					STANDARD_GRAVITY_DIVISOR));
+
+	// ////////
+	// Area //
+	// ////////
+	/**
+	 * A unit of area equal to <code>100 m²</code> (standard name <code>a</code>
+	 * ).
+	 */
+	static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100));
+
+	// ///////////////
+	// Data Amount //
+	// ///////////////
+	/**
+	 * A unit of data amount equal to <code>8 {@link SI#BIT}</code> (BinarY
+	 * TErm, standard name <code>byte</code>).
+	 */
+	static final Unit<Information> BYTE = addUnit(BIT.multiply(8));
+
+	/**
+	 * Equivalent {@link #BYTE}
+	 */
+	static final Unit<Information> OCTET = BYTE;
+
+	// ////////////////////
+	// Electric current //
+	// ////////////////////
+	/**
+	 * A unit of electric charge equal to the centimeter-gram-second
+	 * electromagnetic unit of magnetomotive force, equal to <code>10/4
+	 * &pi;ampere-turn</code> (standard name <code>Gi</code>).
+	 */
+	static final Unit<ElectricCurrent> GILBERT = addUnit(AMPERE
+			.multiply(10).divide(4).multiply(PI).asType(ElectricCurrent.class));
+
+	// //////////
+	// Energy //
+	// //////////
+	/**
+	 * A unit of energy equal to <code>1E-7 J</code> (standard name
+	 * <code>erg</code>).
+	 */
+	static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000));
+
+	/**
+	 * A unit of energy equal to one electron-volt (standard name
+	 * <code>eV</code>, also recognized <code>keV, MeV, GeV</code>).
+	 */
+	static final Unit<Energy> ELECTRON_VOLT = addUnit(JOULE
+			.multiply(ELEMENTARY_CHARGE));
+
+	// ///////////////
+	// Illuminance //
+	// ///////////////
+	/**
+	 * A unit of illuminance equal to <code>1E4 Lx</code> (standard name
+	 * <code>La</code>).
+	 */
+	static final Unit<Illuminance> LAMBERT = addUnit(LUX.multiply(10000));
+
+	// /////////////////
+	// Magnetic Flux //
+	// /////////////////
+	/**
+	 * A unit of magnetic flux equal <code>1E-8 Wb</code> (standard name
+	 * <code>Mx</code>).
+	 */
+	static final Unit<MagneticFlux> MAXWELL = addUnit(WEBER
+			.divide(100000000));
+
+	// /////////////////////////
+	// Magnetic Flux Density //
+	// /////////////////////////
+	/**
+	 * A unit of magnetic flux density equal <code>1000 A/m</code> (standard
+	 * name <code>G</code>).
+	 */
+	static final Unit<MagneticFluxDensity> GAUSS = addUnit(TESLA
+			.divide(10000));
+
+	// /////////
+	// Force //
+	// /////////
+	/**
+	 * A unit of force equal to <code>1E-5 N</code> (standard name
+	 * <code>dyn</code>).
+	 */
+	static final Unit<Force> DYNE = addUnit(NEWTON.divide(100000));
+
+	/**
+	 * A unit of force equal to <code>9.80665 N</code> (standard name
+	 * <code>kgf</code>).
+	 */
+	static final Unit<Force> KILOGRAM_FORCE = addUnit(NEWTON.multiply(
+			STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR));
+
+	/**
+	 * A unit of force equal to <code>{@link #POUND}·{@link #G}</code>
+	 * (standard name <code>lbf</code>).
+	 */
+	static final Unit<Force> POUND_FORCE = addUnit(NEWTON.multiply(
+			1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND)
+			.divide(1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR));
+
+	// /////////
+	// Power //
+	// /////////
+	/**
+	 * A unit of power equal to the power required to raise a mass of 75
+	 * kilograms at a velocity of 1 meter per second (metric, standard name
+	 * <code>hp</code>).
+	 */
+	static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(735.499));
+
+	// ////////////
+	// Pressure //
+	// ////////////
+	/**
+	 * A unit of pressure equal to the average pressure of the Earth's
+	 * atmosphere at sea level (standard name <code>atm</code>).
+	 */
+	static final Unit<Pressure> ATMOSPHERE = addUnit(PASCAL
+			.multiply(101325));
+
+	/**
+	 * A unit of pressure equal to <code>100 kPa</code> (standard name
+	 * <code>bar</code>).
+	 */
+	static final Unit<Pressure> BAR = addUnit(PASCAL.multiply(100000));
+
+	/**
+	 * A unit of pressure equal to the pressure exerted at the Earth's surface
+	 * by a column of mercury 1 millimeter high (standard name <code>mmHg</code>
+	 * ).
+	 */
+	static final Unit<Pressure> MILLIMETRE_OF_MERCURY = addUnit(PASCAL
+			.multiply(133.322));
+
+	/**
+	 * A unit of pressure equal to the pressure exerted at the Earth's surface
+	 * by a column of mercury 1 inch high (standard name <code>inHg</code>).
+	 */
+	static final Unit<Pressure> INCH_OF_MERCURY = addUnit(PASCAL
+			.multiply(3386.388));
+
+	// ///////////////////////////
+	// Radiation dose absorbed //
+	// ///////////////////////////
+	/**
+	 * A unit of radiation dose absorbed equal to a dose of 0.01 joule of energy
+	 * per kilogram of mass (J/kg) (standard name <code>rd</code>).
+	 */
+	static final Unit<RadiationDoseAbsorbed> RAD = addUnit(GRAY
+			.divide(100));
+
+	/**
+	 * A unit of radiation dose effective equal to <code>0.01 Sv</code>
+	 * (standard name <code>rem</code>).
+	 */
+	static final Unit<RadiationDoseEffective> REM = addUnit(SIEVERT
+			.divide(100));
+
+	// ////////////////////////
+	// Radioactive activity //
+	// ////////////////////////
+	/**
+	 * A unit of radioctive activity equal to the activity of a gram of radium
+	 * (standard name <code>Ci</code>).
+	 */
+	static final Unit<RadioactiveActivity> CURIE = addUnit(BECQUEREL
+			.multiply(37000000000L));
+
+	/**
+	 * A unit of radioctive activity equal to 1 million radioactive
+	 * disintegrations per second (standard name <code>Rd</code>).
+	 */
+	static final Unit<RadioactiveActivity> RUTHERFORD = addUnit(BECQUEREL
+			.multiply(1000000));
+
+	// ///////////////
+	// Solid angle //
+	// ///////////////
+	/**
+	 * A unit of solid angle equal to <code>4 <i>&pi;</i> steradians</code>
+	 * (standard name <code>sphere</code>).
+	 */
+	static final Unit<SolidAngle> SPHERE = addUnit(STERADIAN.multiply(4)
+			.multiply(PI).asType(SolidAngle.class));
+
+	// //////////
+	// Volume //
+	// //////////
+
+
+	// /////////////
+	// Viscosity //
+	// /////////////
+	/**
+	 * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit).
+	 */
+	static final Unit<DynamicViscosity> POISE = addUnit(
+			GRAM.divide(CENTI(METRE).multiply(SECOND))).asType(
+			DynamicViscosity.class);
+
+	/**
+	 * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit).
+	 */
+	static final Unit<KinematicViscosity> STOKE = addUnit(
+			CENTI(METRE).pow(2).divide(SECOND))
+			.asType(KinematicViscosity.class);
+
+	// /////////////
+	// Frequency //
+	// /////////////
+	/**
+	 * A unit used to measure the frequency (rate) at which an imaging device
+	 * produces unique consecutive images (standard name <code>fps</code>).
+	 */
+	static final Unit<Frequency> FRAMES_PER_SECOND = addUnit(
+			AbstractUnit.ONE.divide(SECOND)).asType(Frequency.class);
+
+	// //////////
+	// Others //
+	// //////////
+	/**
+	 * A unit used to measure the ionizing ability of radiation (standard name
+	 * <code>Roentgen</code>).
+	 */
+	static final Unit<IonizingRadiation> ROENTGEN = SI.ROENTGEN;
+
+	public String getName() {
+		return getClass().getSimpleName();
+	}
+}
diff --git a/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/package-info.java b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/package-info.java
new file mode 100644
index 0000000..2929189
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/java/org/eclipse/uomo/units/package-info.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Ikayzo and others - initial API and implementation
+ */
+/**
+ * Provides support for programatic unit handling.
+ *
+ * <h3> Standard/NonStandard Units</h3>
+ *      Standard units and prefixes are provided by the
+ *      {@link org.eclipse.uomo.units.SI} class (Système International d'Unités) and
+ *      about 50 non-standard units are available through the
+ *      {@link org.eclipse.uomo.units.impl.system.USCustomary} class.
+ *
+ * <h3>Usage examples:</h3>
+ * [code]
+ *
+ * import static org.eclipse.uomo.units.SI.*;
+ * import static org.eclipse.uomo.units.impl.system.USCustomary.*;
+
+ * public class Main {
+ *     public void main(String[] args) {
+ *
+ *         // Conversion between units (explicit way).
+ *         Unit<Length> sourceUnit = KILO(METRE);
+ *         Unit<Length> targetUnit = MILE;
+ *         UnitConverter uc = sourceUnit.getConverterTo(targetUnit);
+ *         System.out.println(uc.convert(10)); // Converts 10 km to miles.
+ *
+ *         // Same conversion than above, packed in one line.
+ *         System.out.println(KILO(METRE).getConverterTo(MILE).convert(10));
+ *
+ *         // Retrieval of the system unit (identifies the measurement type).
+ *         System.out.println(REVOLUTION.divide(MINUTE).toMetric());
+ *
+ *         // Dimension checking (allows/disallows conversions)
+ *         System.out.println(ELECTRON_VOLT.isCompatible(WATT.times(HOUR)));
+ *
+ *         // Retrieval of the unit dimension (depends upon the current model).
+ *         System.out.println(ELECTRON_VOLT.getDimension());
+ *     }
+ * }
+ *
+ * > 6.2137119223733395
+ * > 6.2137119223733395
+ * > rad/s
+ * > true
+ * > [L]²·[M]/[T]²
+ * [/code]
+ *
+ * <h3>Unit Parameterization</h3>
+ *
+ *     Units are parameterized (e.g. &lt;Time extends {@link org.unitsofmeasure.Quantity Quantity}>) to
+ *     enforce compile-time checks of units/measures consistency, for example:[code]
+ *
+ *     Unit<Time> MINUTE = SECOND.times(60); // Ok.
+ *     Unit<Time> MINUTE = METRE.times(60); // Compile error.
+ *
+ *     Unit<Pressure> HECTOPASCAL = HECTO(PASCAL); // Ok.
+ *     Unit<Pressure> HECTOPASCAL = HECTO(NEWTON); // Compile error.
+ *
+ *     TimeAmount duration = new TimeAmount(2, MINUTE); // Ok.
+ *     TimeAmount duration = new TimeAmount(2, CELSIUS); // Compile error.
+ *
+ *     long milliseconds = duration.longValue(MILLI(SECOND)); // Ok.
+ *     long milliseconds = duration.longValue(POUND); // Compile error.
+ *     [/code]
+ *
+ *     Runtime checks of dimension consistency can be done for more complex cases.
+ *
+ *     [code]
+ *     Unit<Area> SQUARE_FOOT = FOOT.times(FOOT).asType(Area.class); // Ok.
+ *     Unit<Area> SQUARE_FOOT = FOOT.times(KELVIN).asType(Area.class); // Runtime error.
+ *
+ *     Unit<Temperature> KELVIN = Unit.valueOf("K").asType(Temperature.class); // Ok.
+ *     Unit<Temperature> KELVIN = Unit.valueOf("kg").asType(Temperature.class); // Runtime error.
+ *     [/code]
+ *     </p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.5.1, $Date: 2010-08-10 07:04:41 +0100 (Di, 10 Aug 2010) $
+ */
+package org.eclipse.uomo.units;
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties
new file mode 100644
index 0000000..2036f88
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties
@@ -0,0 +1,87 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+# Imperial Units
+org.eclipse.uomo.units.impl.system.Imperial.GALLON_UK            = gal_uk
+# SI Units
+org.eclipse.uomo.units.SI.AMPERE                     = A
+org.eclipse.uomo.units.SI.AMPERE_TURN                = At
+org.eclipse.uomo.units.SI.BECQUEREL                  = Bq
+org.eclipse.uomo.units.SI.CANDELA                    = cd
+org.eclipse.uomo.units.SI.CELSIUS                    = \u00B0C
+org.eclipse.uomo.units.SI.CELSIUS.1                  = \u2103
+org.eclipse.uomo.units.SI.CELSIUS.2                  = Celsius
+org.eclipse.uomo.units.SI.COULOMB                    = C
+org.eclipse.uomo.units.SI.FARAD                      = F
+org.eclipse.uomo.units.SI.GRAM                       = g
+org.eclipse.uomo.units.SI.GRAY                       = Gy
+org.eclipse.uomo.units.SI.HENRY                      = H
+org.eclipse.uomo.units.SI.HERTZ                      = Hz
+org.eclipse.uomo.units.SI.HERTZ.2                    = hertz
+org.eclipse.uomo.units.SI.JOULE                      = J
+org.eclipse.uomo.units.SI.KATAL                      = kat
+org.eclipse.uomo.units.SI.KELVIN                     = K
+org.eclipse.uomo.units.SI.KILOGRAM                   = kg
+org.eclipse.uomo.units.SI.KILOGRAM.1                 = kilogram
+org.eclipse.uomo.units.SI.LUMEN                      = lm
+org.eclipse.uomo.units.SI.LUX                        = lx
+org.eclipse.uomo.units.SI.METRE                      = m
+org.eclipse.uomo.units.SI.MOLE                       = mol
+org.eclipse.uomo.units.SI.NEWTON                     = N
+org.eclipse.uomo.units.SI.OHM                        = \u03A9
+org.eclipse.uomo.units.SI.PASCAL                     = Pa
+org.eclipse.uomo.units.SI.RADIAN                     = rad
+org.eclipse.uomo.units.SI.ROENTGEN                   = R
+org.eclipse.uomo.units.SI.SECOND                     = s
+org.eclipse.uomo.units.SI.SIEMENS                    = S
+org.eclipse.uomo.units.SI.SIEVERT                    = Sv
+org.eclipse.uomo.units.SI.STERADIAN                  = sr
+org.eclipse.uomo.units.SI.TESLA                      = T
+org.eclipse.uomo.units.SI.VOLT                       = V
+org.eclipse.uomo.units.SI.WATT                       = W
+org.eclipse.uomo.units.SI.WEBER                      = Wb
+
+# US Units
+org.eclipse.uomo.units.impl.system.USCustomary.FAHRENHEIT 		 = \u00B0F
+org.eclipse.uomo.units.impl.system.USCustomary.FAHRENHEIT.1      = \u2109
+org.eclipse.uomo.units.impl.system.USCustomary.FOOT              = ft
+org.eclipse.uomo.units.impl.system.USCustomary.HORSEPOWER        = hp
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_LIQUID 	 = gal
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_DRY 	     = gal_dry
+org.eclipse.uomo.units.impl.system.USCustomary.INCH              = in
+org.eclipse.uomo.units.impl.system.USCustomary.KNOT              = kn
+org.eclipse.uomo.units.impl.system.USCustomary.LITER             = l
+org.eclipse.uomo.units.impl.system.USCustomary.MILE    			 = mi
+org.eclipse.uomo.units.impl.system.USCustomary.MILES_PER_HOUR    = mph
+# SI Prefixes
+org.eclipse.uomo.units.impl.format.ParsePrefix.ATTO  = a
+org.eclipse.uomo.units.impl.format.ParsePrefix.CENTI = c
+org.eclipse.uomo.units.impl.format.ParsePrefix.DECI  = d
+org.eclipse.uomo.units.impl.format.ParsePrefix.DEKA  = da
+org.eclipse.uomo.units.impl.format.ParsePrefix.EXA   = E
+org.eclipse.uomo.units.impl.format.ParsePrefix.FEMTO = f
+org.eclipse.uomo.units.impl.format.ParsePrefix.GIGA  = G
+org.eclipse.uomo.units.impl.format.ParsePrefix.HECTO = h
+org.eclipse.uomo.units.impl.format.ParsePrefix.KILO  = k
+org.eclipse.uomo.units.impl.format.ParsePrefix.MEGA  = M
+org.eclipse.uomo.units.impl.format.ParsePrefix.MICRO = \u00B5
+org.eclipse.uomo.units.impl.format.ParsePrefix.MILLI = m
+org.eclipse.uomo.units.impl.format.ParsePrefix.NANO  = n
+org.eclipse.uomo.units.impl.format.ParsePrefix.PETA  = P
+org.eclipse.uomo.units.impl.format.ParsePrefix.PICO  = p
+org.eclipse.uomo.units.impl.format.ParsePrefix.TERA  = T
+org.eclipse.uomo.units.impl.format.ParsePrefix.YOCTO = y
+org.eclipse.uomo.units.impl.format.ParsePrefix.YOTTA = Y
+org.eclipse.uomo.units.impl.format.ParsePrefix.ZEPTO = z
+org.eclipse.uomo.units.impl.format.ParsePrefix.ZETTA = Z
+
+org.eclipse.uomo.units.impl.system.CommonUnits.KILOMETRES_PER_HOUR=kph
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_cn.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_cn.properties
new file mode 100644
index 0000000..6e4834a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_cn.properties
@@ -0,0 +1,17 @@
+org.eclipse.uomo.units.SI.CELSIUS.2                  = \u6442\u6C0F\u6E29\u5EA6
+org.eclipse.uomo.units.SI.GRAM                       = \u514B
+org.eclipse.uomo.units.SI.HERTZ.2                    = \u30D8\u30EB\u30C4
+org.eclipse.uomo.units.SI.METRE                      = \u7C73
+org.eclipse.uomo.units.SI.ROENTGEN                   = \u306E
+org.eclipse.uomo.units.SI.SECOND                     = \u79D2
+org.eclipse.uomo.units.impl.system.USCustomary.LITER             = \u5347
+org.eclipse.uomo.units.impl.system.USCustomary.METER             = \u7C73
+org.eclipse.uomo.units.impl.system.USCustomary.TON               = \u30C8\u30F3
+org.eclipse.uomo.units.impl.format.ParsePrefix.CENTI = \u5398
+org.eclipse.uomo.units.impl.format.ParsePrefix.DECI  = \u5206
+org.eclipse.uomo.units.impl.format.ParsePrefix.DEKA  = \u5341
+org.eclipse.uomo.units.impl.format.ParsePrefix.HECTO = \u767E
+org.eclipse.uomo.units.impl.format.ParsePrefix.KILO  = \u5343
+org.eclipse.uomo.units.impl.format.ParsePrefix.MEGA  = M
+org.eclipse.uomo.units.impl.format.ParsePrefix.MICRO = \u5FAE
+org.eclipse.uomo.units.impl.format.ParsePrefix.MILLI = \u6BEB
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties
new file mode 100644
index 0000000..2204bde
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties
@@ -0,0 +1,45 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+#$Id: messages_de.properties 180 2011-11-13 18:11:17Z keilw $
+
+org.eclipse.uomo.units.impl.system.Imperial.GALLON_UK         = gallone_uk
+org.eclipse.uomo.units.impl.system.Imperial.OUNCE_LIQUID      = fl uz UK
+org.eclipse.uomo.units.impl.system.Imperial.TON_UK            = tonne_uk
+##org.eclipse.uomo.units.impl.system.NonSI.DAY                  = tag
+##org.eclipse.uomo.units.impl.system.NonSI.DAY_SIDEREAL         = tag_sidereal
+##org.eclipse.uomo.units.impl.system.NonSI.POINT                = pkt
+##org.eclipse.uomo.units.impl.system.NonSI.ROENTGEN.1           = R\u00F6ntgen
+org.eclipse.uomo.units.SI.KILOGRAM.1              = kilogramm
+org.eclipse.uomo.units.impl.system.USCustomary.FOOT           = fu\u00DF
+org.eclipse.uomo.units.impl.system.USCustomary.FOOT_SURVEY    = fu\u00DF_survey_us
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_DRY     = gallone_trocken_us
+org.eclipse.uomo.units.impl.system.USCustomary.GRADE          = grad
+org.eclipse.uomo.units.impl.system.USCustomary.HORSEPOWER     = ps
+org.eclipse.uomo.units.impl.system.USCustomary.HOUR           = st
+org.eclipse.uomo.units.impl.system.USCustomary.INCH           = zoll
+org.eclipse.uomo.units.impl.system.USCustomary.LIGHT_YEAR     = lj
+org.eclipse.uomo.units.impl.system.USCustomary.MILE.1         = Meile
+org.eclipse.uomo.units.impl.system.USCustomary.MILES_PER_HOUR = mpst
+org.eclipse.uomo.units.impl.system.USCustomary.OIL_BARREL     = \u00F6lfa\u00DF
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE          = uz
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE_LIQUID   = fl uz US
+##org.eclipse.uomo.units.impl.system.USCustomary.SPHERE         = sph\u00E4re
+org.eclipse.uomo.units.impl.system.USCustomary.TABLESPOON     = Essl
+##org.eclipse.uomo.units.impl.system.USCustomary.TABLESPOON.1   = E\u00DFl\u00F6ffel
+org.eclipse.uomo.units.impl.system.USCustomary.TEASPOON       = teel
+##org.eclipse.uomo.units.impl.system.USCustomary.TEASPOON.1     = Teel\u00F6ffel
+org.eclipse.uomo.units.impl.system.USCustomary.TON            = tonne_us
+##org.eclipse.uomo.units.impl.system.USCustomary.WEEK           = woche
+##org.eclipse.uomo.units.impl.system.USCustomary.YEAR_CALENDAR  = jahr
+##org.eclipse.uomo.units.impl.system.USCustomary.YEAR_SIDEREAL  = jahr_sidereal
+
+org.eclipse.uomo.units.impl.system.CommonUnits.KILOMETRES_PER_HOUR=kmh
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_GB.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_GB.properties
new file mode 100644
index 0000000..45c31eb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_GB.properties
@@ -0,0 +1,19 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+org.eclipse.uomo.units.impl.system.Imperial.GALLON_UK        = gal
+org.eclipse.uomo.units.impl.system.Imperial.OUNCE_LIQUID     = fl oz
+org.eclipse.uomo.units.impl.system.Imperial.TON_UK           = ton
+org.eclipse.uomo.units.impl.system.USCustomary.FOOT_SURVEY   = ft_survey_us
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_DRY    = gallon_dry_us
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_LIQUID = gal_us
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE_LIQUID  = fl oz US
+org.eclipse.uomo.units.impl.system.USCustomary.TON           = ton_us
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_US.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_US.properties
new file mode 100644
index 0000000..bf8349f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_en_US.properties
@@ -0,0 +1,17 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+org.eclipse.uomo.units.impl.system.USCustomary.ELECTRON_VOLT = eV
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_DRY    = gallon_dry
+org.eclipse.uomo.units.impl.system.USCustomary.GALLON_LIQUID = gal
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE_LIQUID  = fl oz
+org.eclipse.uomo.units.impl.system.USCustomary.TON           = ton
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr.properties
new file mode 100644
index 0000000..4b79570
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr.properties
@@ -0,0 +1,37 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+#  See LICENSE.txt for full License
+#
+#  See LICENSE.txt for full License
+#
+#  See LICENSE.txt for full License
+#
+#  See LICENSE.txt for full License
+#
+#  See LICENSE.txt for full License
+#
+#  See LICENSE.txt for full License
+#
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+#  Copyright (c) 2005-2010, Jean-Marie Dautelle, Werner Keil
+#  All rights reserved.
+#
+#  See LICENSE.txt for the Specification License
+#
+# NOTE: as a Java properties file, this file must use the
+# ISO 8859-1 encoding, so all non-ASCII Unicode characters 
+# must be escaped using the \uXXXX syntax.
+# See http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html#encoding
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr_CA.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr_CA.properties
new file mode 100644
index 0000000..605610e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_fr_CA.properties
@@ -0,0 +1,18 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+# NOTE: as a Java properties file, this file must use the
+# ISO 8859-1 encoding, so all non-ASCII Unicode characters 
+# must be escaped using the \uXXXX syntax.
+# See http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html#encoding
+
+org.eclipse.uomo.units.impl.system.USCustomary.FOOT         = pi
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE_LIQUID = oz liq
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ja.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ja.properties
new file mode 100644
index 0000000..00abb2a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ja.properties
@@ -0,0 +1,16 @@
+org.eclipse.uomo.units.SI.CELSIUS.2                  = \u6442\u6C0F\u6E29\u5EA6
+org.eclipse.uomo.units.USCustomary.FAHRENHEIT.1=\u83EF\u6C0F
+org.eclipse.uomo.units.SI.HERTZ.2                    = \u30D8\u30EB\u30C4
+org.eclipse.uomo.units.SI.METRE                      = \u7C73
+org.eclipse.uomo.units.SI.ROENTGEN                   = \u306E
+org.eclipse.uomo.units.SI.SECOND                     = \u79D2
+org.eclipse.uomo.units.impl.system.USCustomary.LITER             = \u5347
+org.eclipse.uomo.units.impl.system.USCustomary.METER             = \u7C73
+org.eclipse.uomo.units.impl.system.USCustomary.TON               = \u30C8\u30F3
+org.eclipse.uomo.units.impl.format.ParsePrefix.CENTI = \u5398
+org.eclipse.uomo.units.impl.format.ParsePrefix.DECI  = \u5206
+org.eclipse.uomo.units.impl.format.ParsePrefix.DEKA  = \u5341
+org.eclipse.uomo.units.impl.format.ParsePrefix.HECTO = \u767E
+org.eclipse.uomo.units.impl.format.ParsePrefix.KILO  = \u5343
+org.eclipse.uomo.units.impl.format.ParsePrefix.MICRO = \u5FAE 
+org.eclipse.uomo.units.impl.format.ParsePrefix.MILLI = \u6BDB
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_pt.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_pt.properties
new file mode 100644
index 0000000..4b822e1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_pt.properties
@@ -0,0 +1,17 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+org.eclipse.uomo.units.impl.system.USCustomary.MINIM             = minim
+##org.eclipse.uomo.units.impl.system.USCustomary.TABLESPOON.1      = Colher de sopa
+##org.eclipse.uomo.units.impl.system.USCustomary.TEASPOON.1        = Colher de ch\u00E1
+org.eclipse.uomo.units.impl.system.USCustomary.TON               = t
+org.eclipse.uomo.units.impl.format.ParsePrefix.MICRO = mu
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ru.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ru.properties
new file mode 100644
index 0000000..37d371a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/impl/format/messages_ru.properties
@@ -0,0 +1,78 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+org.eclipse.uomo.units.SI.BECQUEREL                  = \u0411\u043A
+org.eclipse.uomo.units.SI.CANDELA                    = \u043A\u0434
+org.eclipse.uomo.units.SI.COULOMB                    = \u041A\u043B
+org.eclipse.uomo.units.SI.FARAD                      = \u0424
+org.eclipse.uomo.units.SI.GRAM                       = \u0433
+org.eclipse.uomo.units.SI.GRAY                       = \u0413\u0440
+org.eclipse.uomo.units.SI.HENRY                      = \u0413\u043D
+org.eclipse.uomo.units.SI.HERTZ                      = \u0413\u0446
+org.eclipse.uomo.units.SI.HERTZ.2                    = \u0433\u0435\u0440\u0446
+org.eclipse.uomo.units.SI.JOULE                      = \u0414\u0436
+org.eclipse.uomo.units.SI.KATAL                      = \u043A\u0430\u0442
+org.eclipse.uomo.units.SI.KELVIN                     = \u041A
+org.eclipse.uomo.units.SI.LUMEN                      = \u043B\u043C
+org.eclipse.uomo.units.SI.LUX                        = \u043B\u043A
+org.eclipse.uomo.units.SI.METRE                      = \u043C
+org.eclipse.uomo.units.SI.MOLE                       = \u043C\u043E\u043B\u044C
+org.eclipse.uomo.units.SI.NEWTON                     = \u041D
+org.eclipse.uomo.units.SI.OHM                        = \u041E\u043C
+org.eclipse.uomo.units.SI.PASCAL                     = \u041F\u0430
+org.eclipse.uomo.units.SI.RADIAN                     = \u0440\u0430\u0434
+org.eclipse.uomo.units.SI.SECOND                     = \u0441
+org.eclipse.uomo.units.SI.SIEMENS                    = \u0421\u043C
+org.eclipse.uomo.units.SI.SIEVERT                    = \u0417\u0432
+org.eclipse.uomo.units.SI.STERADIAN                  = \u0441\u0440
+org.eclipse.uomo.units.SI.TESLA                      = \u0422\u043B
+org.eclipse.uomo.units.SI.VOLT                       = \u0412
+org.eclipse.uomo.units.SI.WATT                       = \u0412\u0442
+org.eclipse.uomo.units.SI.WEBER                      = \u0412\u0431
+org.eclipse.uomo.units.impl.system.USCustomary.ELECTRON_VOLT     = e\u0412
+org.eclipse.uomo.units.impl.system.USCustomary.FAHRENHEIT        = \u00B0\u0424
+org.eclipse.uomo.units.impl.system.USCustomary.FAHRENHEIT.0      = \u00B0\u0424
+org.eclipse.uomo.units.impl.system.USCustomary.FLUID_DRAM        = \u0434\u0440\u0430\u0445\u043C\u0430
+org.eclipse.uomo.units.impl.system.USCustomary.HOUR              = \u0447
+org.eclipse.uomo.units.impl.system.USCustomary.LITER             = \u043B
+org.eclipse.uomo.units.impl.system.USCustomary.METER             = \u043C
+org.eclipse.uomo.units.impl.system.USCustomary.MILES_PER_HOUR    = \u043C\u0438\u043B\u044C \u0432 \u0447\u0430\u0441
+org.eclipse.uomo.units.impl.system.USCustomary.MINIM             = \u043C\u0438\u043D\u0438\u043C
+org.eclipse.uomo.units.impl.system.USCustomary.MINUTE            = \u0447
+org.eclipse.uomo.units.impl.system.USCustomary.OIL_BARREL        = \u0431\u0430\u0440\u0440\u0435\u043B\u044C
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE             = \u0443\u043D\u0446\u0438\u044F
+org.eclipse.uomo.units.impl.system.USCustomary.OUNCE_LIQUID      = \u0436\u0438\u0434\u043A\u0430\u044F \u0443\u043D\u0446\u0438\u044F
+org.eclipse.uomo.units.impl.system.USCustomary.RANKINE           = \u00B0P
+org.eclipse.uomo.units.impl.system.USCustomary.RANKINE.0         = \u00B0P
+org.eclipse.uomo.units.impl.system.USCustomary.TABLESPOON        = \u0441\u0442 \u043B\u043E\u0436\u043A\u0430
+org.eclipse.uomo.units.impl.system.USCustomary.TEASPOON          = \u0447\u0430\u0439\u043D\u0430\u044F \u043B\u043E\u0436\u043A\u0430
+org.eclipse.uomo.units.impl.system.USCustomary.TON               = \u0422
+org.eclipse.uomo.units.impl.format.ParsePrefix.ATTO  = a
+org.eclipse.uomo.units.impl.format.ParsePrefix.CENTI = c
+org.eclipse.uomo.units.impl.format.ParsePrefix.DECI  = \u0434
+org.eclipse.uomo.units.impl.format.ParsePrefix.DEKA  = \u0434\u0430
+org.eclipse.uomo.units.impl.format.ParsePrefix.EXA   = \u042D
+org.eclipse.uomo.units.impl.format.ParsePrefix.FEMTO = \u0444
+org.eclipse.uomo.units.impl.format.ParsePrefix.GIGA  = \u0413
+org.eclipse.uomo.units.impl.format.ParsePrefix.HECTO = \u0433
+org.eclipse.uomo.units.impl.format.ParsePrefix.KILO  = \u043A
+org.eclipse.uomo.units.impl.format.ParsePrefix.MEGA  = M
+org.eclipse.uomo.units.impl.format.ParsePrefix.MICRO = \u043C\u043A
+org.eclipse.uomo.units.impl.format.ParsePrefix.MILLI = \u043C
+org.eclipse.uomo.units.impl.format.ParsePrefix.NANO  = \u043D
+org.eclipse.uomo.units.impl.format.ParsePrefix.PETA  = \u041F
+org.eclipse.uomo.units.impl.format.ParsePrefix.PICO  = \u043F
+org.eclipse.uomo.units.impl.format.ParsePrefix.TERA  = T
+org.eclipse.uomo.units.impl.format.ParsePrefix.YOCTO = \u0438
+org.eclipse.uomo.units.impl.format.ParsePrefix.YOTTA = \u0418
+org.eclipse.uomo.units.impl.format.ParsePrefix.ZEPTO = \u0437
+org.eclipse.uomo.units.impl.format.ParsePrefix.ZETTA = \u0417
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages.properties
new file mode 100644
index 0000000..9c1ab26
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages.properties
@@ -0,0 +1,85 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+
+LocalFormat_Pattern = %s
+
+NonSI_R = R
+
+NonSI_R_name = Roentgen
+
+SI_A = A
+
+SI_At = At
+
+SI_Bq = Bq
+
+SI_C = C
+
+SI_F = F
+
+SI_Gy = Gy
+
+SI_H = H
+
+SI_Hz = Hz
+
+SI_J = J
+
+SI_K = K
+
+SI_N = N
+
+SI_OhmS = \u03A9
+
+SI_Pa = Pa
+
+SI_S = S
+
+SI_Sv = Sv
+
+SI_T = T
+
+SI_V = V
+
+SI_W = W
+
+SI_Wb = Wb
+
+SI_bit = bit
+
+SI_cd = cd
+
+SI_kat = kat
+
+SI_kg = kg
+
+SI_kg_name = kilogram
+
+SI_lm = lm
+
+SI_lx = lx
+
+SI_m = m
+
+SI_m_name = metre
+
+SI_mol = mol
+
+SI_rad = rad
+
+SI_s = s
+
+SI_sr = sr
+
+##SymbolMapImpl_unableToCast = unable to cast 
+
+US_lb_name = Pound
diff --git a/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages_de.properties b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages_de.properties
new file mode 100644
index 0000000..0bfabea
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/main/resources/org/eclipse/uomo/units/messages_de.properties
@@ -0,0 +1,20 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil, Ikayzo and others - initial API and implementation
+#
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+
+NonSI_R_name = R\u00F6ntgen
+
+SI_kg_name = kilogramm
+
+SI_m_name = meter
+
+US_lb_name = Pfund
diff --git a/bundles/org.eclipse.uomo.units/src/site/.gitignore b/bundles/org.eclipse.uomo.units/src/site/.gitignore
new file mode 100644
index 0000000..35815fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/.gitignore
@@ -0,0 +1 @@
+/.svn
diff --git a/bundles/org.eclipse.uomo.units/src/site/apt/.gitignore b/bundles/org.eclipse.uomo.units/src/site/apt/.gitignore
new file mode 100644
index 0000000..35815fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/apt/.gitignore
@@ -0,0 +1 @@
+/.svn
diff --git a/bundles/org.eclipse.uomo.units/src/site/apt/implementations.apt b/bundles/org.eclipse.uomo.units/src/site/apt/implementations.apt
new file mode 100644
index 0000000..655f528
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/apt/implementations.apt
@@ -0,0 +1,16 @@
+Implementations
+
+  Some projects that are known to implement the <Unit of Measurement> API are:
+
+    * Open Source Projects
+    
+        * {{{http://www.eclipse.org/uomo/}UOMo}} at Eclipse
+
+        * {{{http://jscience.org/}JScience}}
+    
+    * Commercial / Closed Source
+    
+        * Web Applications at {{{http://www.globalservices.bt.com/}BT Global Services}}
+
+  If you would like to add your product to this list, please let us known on the
+  {{{mail-lists.html}mailing list}}.
diff --git a/bundles/org.eclipse.uomo.units/src/site/apt/index.apt b/bundles/org.eclipse.uomo.units/src/site/apt/index.apt
new file mode 100644
index 0000000..9769b9f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/apt/index.apt
@@ -0,0 +1,87 @@
+~~ $Id: index.apt 154 2011-11-01 11:21:06Z martdesruisseaux $
+~~ Unit-API - Units of Measurement API for Java (http://www.unitsofmeasurement.org)
+~~ Copyright (c) 2005-2010, Unit-API contributors, JScience and others
+~~ All rights reserved.
+~~
+~~ See LICENSE.txt for details.
+~~
+                    -----------------------------------------------------
+                    UOMo home page
+                    -----------------------------------------------------
+                    Werner Keil, Martin Desruisseaux
+                    -----------------------------------------------------
+                    $Date: 2011-11-01 12:21:06 +0100 (Di, 01 Nov 2011) $
+                    -----------------------------------------------------
+
+
+Eclipse UOMo
+
++------------------------------------------+
+Unit-API contributors, JScience and others
++------------------------------------------+
+
+  Copyright (c) 2005-2010, Unit-API contributors, JScience and others
+  All rights reserved.
+
+  See LICENSE.txt for details.
+
+[./images/icon.png] Logo
+
+  The <Unit of Measurement> library provides a set of Java language programming interfaces for
+  handling units and quantities. The interfaces provide a layer which separates client code,
+  which would call the API, from library code, which implements the API. Various groups have
+  implemented the API, see the {{{./implementations.html}list of known implementations}} for details.
+
+* The project
+
+  The project is {{{http://unitsofmeasure.googlecode.com/}hosted on Google Code}}. It runs a public
+  {{{./mail-lists.html}mailing list}} for user and developer questions, other issues, and general
+  discussion.
+
+  The <Unit of Measurement> library is free software. It may be used, modified and redistributed by
+  anyone for any purpose requiring only maintaining the copyright and license terms on the source
+  code and derivative files. See the {{{./license.html}license}} page for details.
+
+
+* Links
+
+    * {{{./apidocs/index.html}Browse javadoc}}
+
+    * {{{http://hudson.geomatys.com/job/Unit-API/}Nightly builds}}
+
+    * {{{./mail-lists.html}Mailing lists}}
+
+    * {{{http://www.unitsofmeasure.org/}The Unified Code for Units of Measure (UCUM)}}
+
+    * {{{./legacy/JSR-275.odt}Legacy JSR-275 specification draft}} (LibreOffice/OpenOffice.org document)
+
+
+* UCUM
+
+** What is it?
+
+  The Unified Code for Units of Measure is a code system intended to include all units of measures
+  being contemporarily used in international science, engineering, and business. The purpose is to
+  facilitate unambiguous electronic communication of quantities together with their units. The focus
+  is on electronic communication, as opposed to communication between humans. A typical application
+  of The Unified Code for Units of Measure are electronic data interchange (EDI) protocols, but there
+  is nothing that prevents it from being used in other types of machine communication.
+
+** How does it relate?
+
+  The Unified Code for Units of Measure is inspired by and heavily based on ISO 2955-1983, ANSI X3.50-1986,
+  and HL7's extensions called "ISO+". The respective ISO and ANSI standards are both entitled Representation
+  of [...] units in systems with limited character sets where ISO 2955 refers to SI and other units provided
+  by ISO 1000-1981, while ANSI X3.50 extends ISO 2955 to include U.S. customary units. Because these standards
+  carry the restriction of "limited character sets" in their names they seem to be of less value today where
+  graphical user interface and laser printers are in wide-spread use, which is why the European standard
+  ENV 12435 in its clause 7.3 declares ISO 2955 obsolete.
+
+  ENV 12435 is dedicated exclusively to the communication of measurements between humans in display
+  and print, and does not provide codes that can be used in communication between systems. It does
+  not even provide a specification that would allow communication of units from one system to the
+  screen or printer of another system. The issue about displaying units in the common style defined
+  by the 9th <Conférence Générale des Poids et Mesures> (CGPM) in 1947 is not just the character set.
+  Although The Unicode Standard and its predecessor ISO/IEC 10646 is the richest character set ever
+  it is still not enough to specify the presentation of units because there are important typographical
+  details such as superscripts, subscripts, roman and italics.
diff --git a/bundles/org.eclipse.uomo.units/src/site/resources/.gitignore b/bundles/org.eclipse.uomo.units/src/site/resources/.gitignore
new file mode 100644
index 0000000..35815fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/resources/.gitignore
@@ -0,0 +1 @@
+/.svn
diff --git a/bundles/org.eclipse.uomo.units/src/site/resources/images/.gitignore b/bundles/org.eclipse.uomo.units/src/site/resources/images/.gitignore
new file mode 100644
index 0000000..35815fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/resources/images/.gitignore
@@ -0,0 +1 @@
+/.svn
diff --git a/bundles/org.eclipse.uomo.units/src/site/resources/images/icon.png b/bundles/org.eclipse.uomo.units/src/site/resources/images/icon.png
new file mode 100644
index 0000000..97a40df
--- /dev/null
+++ b/bundles/org.eclipse.uomo.units/src/site/resources/images/icon.png
Binary files differ
diff --git a/bundles/org.eclipse.uomo.util.tests/.classpath b/bundles/org.eclipse.uomo.util.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.util.tests/.gitignore b/bundles/org.eclipse.uomo.util.tests/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.util.tests/.project b/bundles/org.eclipse.uomo.util.tests/.project
new file mode 100644
index 0000000..a02c8bb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.util.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.util.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.util.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d93f741
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.util.tests
+Bundle-SymbolicName: org.eclipse.uomo.util.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.util;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.uomo.util.test,
+ org.eclipse.uomo.util.test.numbers
+Require-Bundle: org.junit;bundle-version="4.8.2"
diff --git a/bundles/org.eclipse.uomo.util.tests/build.properties b/bundles/org.eclipse.uomo.util.tests/build.properties
new file mode 100644
index 0000000..ced5f40
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.util.tests/pom.xml b/bundles/org.eclipse.uomo.util.tests/pom.xml
new file mode 100644
index 0000000..1668ae3
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo.bundles</artifactId>
+    	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>org.eclipse.uomo.util.tests</artifactId>
+  <name>UOMo Util Tests</name>
+  <packaging>eclipse-test-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/Iso8601DateUtilityTests.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/Iso8601DateUtilityTests.java
new file mode 100644
index 0000000..7568053
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/Iso8601DateUtilityTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.util.test;
+
+import junit.framework.TestCase;
+
+import org.eclipse.uomo.util.impl.Iso8601Date;
+import org.junit.Test;
+
+public class Iso8601DateUtilityTests extends TestCase {
+   
+	private Iso8601Date du;
+	
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		du = new Iso8601Date();
+	}
+	
+	@Test
+	public void testFullDate() {
+		String st;
+		st = du.parse("20071017111114.789", Iso8601Date.ISO_DATE_VALIDATION_FULL, Iso8601Date.OPTIONAL);
+		assertTrue(st, st == null);
+		st = du.parse("20061027000000.0020", Iso8601Date.ISO_DATE_VALIDATION_FULL, Iso8601Date.OPTIONAL);
+		assertTrue(st, st == null);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/NumberFormatUtilityTest.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/NumberFormatUtilityTest.java
new file mode 100644
index 0000000..0a75e9d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/NumberFormatUtilityTest.java
@@ -0,0 +1,310 @@
+package org.eclipse.uomo.util.test;
+
+import static org.eclipse.uomo.util.numbers.UOMoNumberFormatException.Kind.*;
+import static org.junit.Assert.*;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import org.eclipse.uomo.util.numbers.NumberFormatUtilities;
+import org.eclipse.uomo.util.numbers.UOMoNumberFormatException;
+import org.eclipse.uomo.util.numbers.UOMoNumberFormatException.Kind;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class NumberFormatUtilityTest {
+
+	@Test
+	public void testInteger() {
+		assertValidInt("0");
+		assertValidInt("-0");
+		assertValidInt("+0");
+		assertValidInt("1");
+		assertValidInt("-1");
+		assertValidInt("10000000000000000000000000000000000000000000000009000");
+
+		assertInvalidInt("NaN");
+		assertInvalidInt("INF");
+		assertInvalidInt("+INF");
+		assertInvalidInt("-INF");
+		assertInvalidInt("1.0e0");
+		assertInvalidInt("1.0e-0");
+		assertInvalidInt("1.0e-1");
+		assertInvalidInt("1.0e1");
+		assertInvalidInt("1.0e10000000000000000000000000000000000000000000000000000000");
+		assertValidInt("12678967543233");
+		assertValidInt("+100000");
+		assertInvalidInt("-1E4");
+		assertInvalidInt("1267.43233E12");
+		assertInvalidInt("12.78e-2");
+		assertValidInt("12");
+		assertInvalidInt("-1.23");
+		assertInvalidInt("012.78e-2");
+		assertValidInt("012");
+		assertInvalidInt("-01.23");
+		assertInvalidInt("12678967.543233");
+		assertInvalidInt("+100000.00");
+		assertInvalidInt("+100,000");
+		assertValidInt("210");
+
+		assertInvalidInt("-");
+		assertInvalidInt("-a");
+		assertInvalidInt("-b");
+		assertInvalidInt(".");
+		assertInvalidInt("+.");
+		assertInvalidInt("-.");
+		assertInvalidInt(".0");
+		assertInvalidInt("+.0");
+		assertInvalidInt("-.0");
+
+		assertInvalidInt("0e0");
+		assertInvalidInt("e0");
+		assertInvalidInt("0e");
+
+		assertParseInt("0", 0);
+		assertParseInt("-0", 0);
+		assertParseInt("+0", 0);
+		assertParseInt("1", 1);
+		assertParseInt("-1", -1);
+		assertParseFailInt("10000000000000000000000000000000000000000000000009000");
+		assertParseFailInt("-10000000000000000000000000000000000000000000000000090");
+		assertParseFailInt("1.0e10000000000000000000000000000000000000000000000000000000");
+		assertParseFailInt("12678967543233");
+		assertParseInt("126789673", 126789673);
+		assertParseInt("+100000", 100000);
+		assertParseInt("12", 12);
+		assertParseInt("012", 12);
+		assertParseInt("210", 210);
+	}
+
+	@Test
+	@Ignore
+	public void _estReal() {
+		checkParse("0", new BigDecimal("0"));
+		checkParseInvalid("e", TEXT_FORMAT);
+		checkParse("-0", new BigDecimal("-0"));
+		checkParse("+0", new BigDecimal("+0"));
+		checkParse("1", new BigDecimal("1"));
+		checkParse("-1", new BigDecimal("-1"));
+		checkParse(
+				"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000",
+				new BigDecimal(
+						"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000"));
+		checkParse(
+				"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090",
+				new BigDecimal(
+						"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090"));
+		checkParseInvalid("NaN", NaN);
+		checkParseInvalid("INF", PINF);
+		checkParseInvalid("+INF", PINF);
+		checkParseInvalid("-INF", NINF);
+		checkParse("1.0e0", new BigDecimal("1.0e0"));
+		checkParse("1.0e-0", new BigDecimal("1.0e-0"));
+		checkParse("1.0e-1", new BigDecimal("1.0e-1"));
+		checkParse("1.0e1", new BigDecimal("1.0e1"));
+		checkParseInvalid(
+				"1.0e10000000000000000000000000000000000000000000000000000000",
+				UOMoNumberFormatException.Kind.SIZE);
+		checkParse("12678967543233", new BigDecimal("12678967543233"));
+		checkParse("+100000", new BigDecimal("+100000"));
+		checkParse("-1E4", new BigDecimal("-1E4"));
+		checkParse("1267.43233E12", new BigDecimal("1267.43233E12"));
+		checkParse("12.78e-2", new BigDecimal("12.78e-2"));
+		checkParse("12", new BigDecimal("12"));
+		checkParse("-1.23", new BigDecimal("-1.23"));
+		checkParse("012.78e-2", new BigDecimal("012.78e-2"));
+		checkParse("012", new BigDecimal("012"));
+		checkParse("-01.23", new BigDecimal("-01.23"));
+		checkParse("12678967.543233", new BigDecimal("12678967.543233"));
+		checkParse("+100000.00", new BigDecimal("+100000.00"));
+		checkParse("210", new BigDecimal("210"));
+
+		checkParseInvalid("-", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-a", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-b", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(".", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("+.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(".0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("+.0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-.0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+
+		checkParse("0e0", new BigDecimal("0e0"));
+		checkParseInvalid("e0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("0e", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+
+		Locale.setDefault(Locale.GERMANY);
+
+		checkParse("0", new BigDecimal("0"));
+		checkParseInvalid("e", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParse("-0", new BigDecimal("-0"));
+		checkParse("+0", new BigDecimal("+0"));
+		checkParse("1", new BigDecimal("1"));
+		checkParse("-1", new BigDecimal("-1"));
+		checkParse(
+				"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000",
+				new BigDecimal(
+						"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000"));
+		checkParse(
+				"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090",
+				new BigDecimal(
+						"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090"));
+		checkParseInvalid("NaN", UOMoNumberFormatException.Kind.NaN);
+		checkParseInvalid("INF", UOMoNumberFormatException.Kind.PINF);
+		checkParseInvalid("+INF", UOMoNumberFormatException.Kind.PINF);
+		checkParseInvalid("-INF", UOMoNumberFormatException.Kind.NINF);
+		checkParse("1.0e0", new BigDecimal("1.0e0"));
+		checkParse("1.0e-0", new BigDecimal("1.0e-0"));
+		checkParse("1.0e-1", new BigDecimal("1.0e-1"));
+		checkParse("1.0e1", new BigDecimal("1.0e1"));
+		checkParseInvalid(
+				"1.0e10000000000000000000000000000000000000000000000000000000",
+				UOMoNumberFormatException.Kind.SIZE);
+		checkParse("12678967543233", new BigDecimal("12678967543233"));
+		checkParse("+100000", new BigDecimal("+100000"));
+		checkParse("-1E4", new BigDecimal("-1E4"));
+		checkParse("1267.43233E12", new BigDecimal("1267.43233E12"));
+		checkParse("12.78e-2", new BigDecimal("12.78e-2"));
+		checkParse("12", new BigDecimal("12"));
+		checkParse("-1.23", new BigDecimal("-1.23"));
+		checkParse("12678967.543233", new BigDecimal("12678967.543233"));
+		checkParse("+100000.00", new BigDecimal("+100000.00"));
+		checkParse("210", new BigDecimal("210"));
+
+		checkParseInvalid("", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(null, UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-a", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-b", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(".", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("+.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(".0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("+.0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("-.0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1/2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("0.", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("a 12", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 12", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 12 ", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 12 a", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 12a", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 1.2e2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 1.2e2 ", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 1.2e2 a",
+				UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid(" 1.2e2a", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1 .2e2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1. 2e2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1.2 e2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1.2e 2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1.2e2 ", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+
+		checkParse("0e0", new BigDecimal("0e0"));
+		checkParse("0e00", new BigDecimal("0e00"));
+		checkParseInvalid("e0", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("0e", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+		checkParseInvalid("1e0.2", UOMoNumberFormatException.Kind.TEXT_FORMAT);
+
+		checkParse("0", new BigDecimal("0"));
+		checkParse("-0", new BigDecimal("-0"));
+		checkParse("+0", new BigDecimal("+0"));
+		checkParse("1", new BigDecimal("1"));
+		checkParse("-1", new BigDecimal("-1"));
+		checkParse(
+				"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000",
+				new BigDecimal(
+						"10000000000000000000000000000000000000000000000009000.000000000000000000000000000000000000000000000000"));
+		checkParse(
+				"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090",
+				new BigDecimal(
+						"-10000000000000000000000000000000000000000000000000090.000000000000000000000000000000000000000000000090"));
+		checkParseInvalid("NaN", UOMoNumberFormatException.Kind.NaN);
+		checkParseInvalid("INF", UOMoNumberFormatException.Kind.PINF);
+		checkParseInvalid("+INF", UOMoNumberFormatException.Kind.PINF);
+		checkParseInvalid("-INF", UOMoNumberFormatException.Kind.NINF);
+		checkParse("1.0e0", new BigDecimal("1.0e0"));
+		checkParse("1.0e-0", new BigDecimal("1.0e-0"));
+		checkParse("1.0e2", new BigDecimal("1.0e2"));
+		checkParse("1.0e-1", new BigDecimal("1.0e-1"));
+		checkParse("1.0e1", new BigDecimal("1.0e1"));
+		checkParseInvalid(
+				"1.0e10000000000000000000000000000000000000000000000000000000",
+				UOMoNumberFormatException.Kind.SIZE);
+		checkParse("12678967543233", new BigDecimal("12678967543233"));
+		checkParse("126789673", new BigDecimal("126789673"));
+		checkParse("+100000", new BigDecimal("+100000"));
+		checkParse("-1E4", new BigDecimal("-1E4"));
+		checkParse("1E-4", new BigDecimal("1E-4"));
+		checkParse("1267.43233E12", new BigDecimal("1267.43233E12"));
+		checkParse("12.78e-2", new BigDecimal("12.78e-2"));
+		checkParse("12", new BigDecimal("12"));
+		checkParse("-1.23", new BigDecimal("-1.23"));
+		checkParse("012.78e-2", new BigDecimal("012.78e-2"));
+		checkParse("012", new BigDecimal("012"));
+		checkParse("-01.23", new BigDecimal("-01.23"));
+		checkParse("12678967.543233", new BigDecimal("12678967.543233"));
+		checkParse("+100000.00", new BigDecimal("+100000.00"));
+		checkParse("210", new BigDecimal("210"));
+		checkParse("0e0", new BigDecimal("0e0"));
+
+	}
+
+	private void checkParse(String source, BigDecimal d) {
+		try {
+			BigDecimal v = NumberFormatUtilities.parseReal(source, null);
+			assertTrue("Failed to parse " + source + " (" + d.toPlainString()
+					+ "/" + v.toPlainString() + ")", v.equals(d));
+		} catch (UOMoNumberFormatException e) {
+			fail("Failed to parse " + source + ": " + e.getMessage() + " ["
+					+ e.getMessageForKind() + "]");
+		}
+	}
+
+	private void checkParseInvalid(String source, Kind kind) {
+		try {
+			NumberFormatUtilities.parseReal(source, null);
+			fail("unexpectedly ok: '" + source + "'");
+		} catch (UOMoNumberFormatException e) {
+			assertTrue(
+					"parsing failed for " + source + ", message = "
+							+ e.getMessage() + ", should be "
+							+ UOMoNumberFormatException.getMessageForKind(kind)
+							+ " but was " + e.getMessageForKind(),
+					e.getKind() == kind);
+		}
+	}
+
+	private void assertValidInt(String source) {
+		String v = NumberFormatUtilities.validateInteger(source);
+		assertTrue(source + ": unexpected error: " + v, v == null);
+	}
+
+	private void assertInvalidInt(String source) {
+		assertTrue("unexpectedly ok: '" + source + "'",
+				NumberFormatUtilities.validateInteger(source) != null);
+	}
+
+	private void assertParseFailInt(String source) {
+		try {
+			NumberFormatUtilities.parseInteger(source);
+		} catch (NumberFormatException e) {
+			// that's ok
+		}
+	}
+
+	private void assertParseInt(String source, long d) {
+		try {
+			long v = NumberFormatUtilities.parseInteger(source);
+			assertTrue(source + ": parsing value wrong for " + Long.toString(d)
+					+ ": " + Long.toString(v), d == v);
+		} catch (NumberFormatException e) {
+			assertTrue(
+					"parsing failed for " + source + ", message = "
+							+ e.getMessage(), false);
+		}
+
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UOMoTestConfiguration.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UOMoTestConfiguration.java
new file mode 100644
index 0000000..875aeff
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UOMoTestConfiguration.java
@@ -0,0 +1,70 @@
+package org.eclipse.uomo.util.test;
+
+/**
+ * note: in osx, you cannot have spaces in the name of the temporary directory
+ * 
+ * @author grahame
+ * 
+ */
+
+public interface UOMoTestConfiguration {
+
+    /**
+     * The starting location, often the path to the test suite/test file that is
+     * run by the launcher. (i.e. org.eclipse.ohf.h3et.tests when running the
+     * AllH3etTests)
+     */
+    public static final String STARTDIR = System.getenv("STARTDIR") != null ? System
+	    .getenv("STARTDIR")
+	    : "./";
+
+    // don't run third party programs
+    public final static boolean SKIP_THIRD_PARTY = System
+	    .getenv("SKIP_THIRD_PARTY") != null;
+
+    /**
+     * Third party programs
+     * 
+     * on Windows, we use Firefox and WinMerge
+     * 
+     * on OSX, we use Firefox and FileMerge (from XCode)
+     */
+
+    // root folder of third party programs
+    public final static String BIN_DIR_WIN = System.getenv("ProgramFiles") != null ? System
+	    .getenv("ProgramFiles")
+	    : "C:/Program Files";
+    public final static String BROWSER_PATH = System.getProperty("os.name")
+	    .toLowerCase().startsWith("mac os x") ? "open " : BIN_DIR_WIN
+	    + "/Mozilla FireFox/FireFox.exe";
+    public final static String COMPARE_PATH = System.getProperty("os.name")
+	    .toLowerCase().startsWith("mac os x") ? "/usr/bin/opendiff" : // consult
+									  // FileMerge.app
+									  // help
+									  // doco
+									  // (part
+									  // of
+									  // XCode)
+									  // +
+									  // remember
+									  // to
+									  // make
+									  // it
+									  // executable
+	    BIN_DIR_WIN + "/WinMerge/WinMerge.exe";
+
+    /**
+     * Temp dir for generating files
+     */
+    public static final String TEMP_PATH = System.getenv("TEMP") != null ? System
+	    .getenv("TEMP")
+	    : (System.getProperty("os.name").toLowerCase().startsWith(
+		    "mac os x") ? "/temp/" : "C:/temp/");
+
+    public static final String PLUGIN_ID = "org.eclipse.uomo.util";
+    public static final String RESOURCE_PATH = STARTDIR + "../" + PLUGIN_ID
+	    + "/src/main/resources/";
+
+    public static final String TEMP_FILENAME = TEMP_PATH + "/res_tmp";
+
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UUIDTest.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UUIDTest.java
new file mode 100644
index 0000000..f2ab503
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UUIDTest.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.util.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.UUID;
+
+import org.junit.Test;
+
+/**
+ * Generates a (mostly) ASN.1 complaint UUID. <br>
+ * Under Windows the MAC address of the machine is used, under Linux and other
+ * OS's a randomly generated construct using the SHA-1 message digest is used.
+ * It is thus possible that UUIDs will not be completely unique under non
+ * Windows platforms, but given the number of bits of random data used to
+ * generate the fake MAC addresses for non Windows machines, it is very unlikely
+ * any collosions will every occur in practice.
+ * 
+ * @author Glenn Deen
+ * @since IHII Phase 1
+ * 
+ */
+public class UUIDTest {
+
+	/**
+	 * Holds the time this alogorithm was last run
+	 */
+	private static long lastTimeCalled = 0;
+
+	/**
+	 * 
+	 */
+	private static String MAC = null;
+
+	/**
+	 * Generates and returns a formatted UUID holding a 128 bit UUID in the
+	 * form: AABBCCDDEEFF-GGHH-IIJJ-KKLLMMNNOOPP
+	 * 
+	 * @return the generated uuid
+	 */
+	static String generate() {
+		UUID uuid = UUID.randomUUID();
+		lastTimeCalled = System.currentTimeMillis();
+		return uuid.toString();
+	}
+
+	/**
+	 * Generate a new UUID prefixed by urn:uuid:
+	 */
+	static String generateURN() {
+		return "urn:uuid:" + UUID.randomUUID();
+	}
+
+	@Test
+	public void testUUID() {
+		String uuid = generate();
+		assertNotNull(uuid);
+		assertTrue(uuid.contains("-"));
+	}
+
+	/**
+	 * Runs a simple test of the UUID class, generating a set of UUIDs
+	 * 
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		int count = 100;
+		System.out.println("Generating " + count + " test URNs ...");
+		long start = System.currentTimeMillis();
+		for (int i = 0; i < count; i++)
+			System.out.println(UUID.randomUUID());
+		long end = System.currentTimeMillis();
+		System.out.println("Generated " + count + " URN's at rate of "
+				+ Math.round((double) count / (double) (end - start) * 1000)
+				+ " per second");
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UtilityTests.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UtilityTests.java
new file mode 100644
index 0000000..f88dbb0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/UtilityTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.util.test;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ Iso8601DateUtilityTests.class,
+		NumberFormatUtilityTest.class })
+public class UtilityTests {
+
+	/**
+	 * For use with JUnit3 runner
+	 * 
+	 * @deprecated
+	 */
+	public static Test suite() {
+		return new JUnit4TestAdapter(UtilityTests.class);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/internal/Activator.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/internal/Activator.java
new file mode 100644
index 0000000..65add65
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/internal/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.uomo.util.test.internal;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.uomo.util.test";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/IndianNumberDemos.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/IndianNumberDemos.java
new file mode 100644
index 0000000..b9b6019
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/IndianNumberDemos.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.test.numbers;
+
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.impl.IndianNumberSpeller;
+
+public class IndianNumberDemos {
+
+	public static void main(String args[]) throws Exception {
+		// Reader buff = new BufferedReader(new InputStreamReader(
+		// System.in));
+		System.out.println("Display massage number to Text!");
+		ISpeller num = IndianNumberSpeller.of();
+		System.out.println("Spelling: " + num.spell(10) + ".");
+		System.out.println("Spelling: " + num.spell(15) + ".");
+		System.out.println("Spelling: " + num.spell(50) + ".");
+		System.out.println("Spelling: " + num.spell(99) + ".");
+		System.out.println("Spelling: " + num.spell(150) + ".");
+		System.out.println("Spelling: " + num.spell(234) + ".");
+		System.out.println("Spelling: " + num.spell(250) + ".");
+		System.out.println("Spelling: " + num.spell(2500) + ".");
+		System.out.println("Spelling: " + num.spell(3900) + ".");
+		System.out.println("Spelling: " + num.spell(250700) + ".");
+		// System.out.println("Spelling: " + num.spell(Integer.MAX_VALUE + 1) +
+		// ".");
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/RomanNumberDemos.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/RomanNumberDemos.java
new file mode 100644
index 0000000..0e9bad8
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/RomanNumberDemos.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 1996, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.test.numbers;
+
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.impl.RomanNumberSpeller;
+
+public class RomanNumberDemos {
+
+	public static void main(String args[]) throws Exception {
+		System.out.println("Display massage number to Text!");
+		final ISpeller num = RomanNumberSpeller.of();
+		System.out.println("Spelling: " + num.spell(10) + ".");
+		System.out.println("Spelling: " + num.spell(15) + ".");
+		System.out.println("Spelling: " + num.spell(50) + ".");
+		System.out.println("Spelling: " + num.spell(99) + ".");
+		System.out.println("Spelling: " + num.spell(150) + ".");
+		System.out.println("Spelling: " + num.spell(234) + ".");
+		System.out.println("Spelling: " + num.spell(250) + ".");
+		System.out.println("Spelling: " + num.spell(2500) + ".");
+		System.out.println("Spelling: " + num.spell(3900) + ".");
+		// System.out.println("Spelling: " + num.spell(4000) + ".");
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/SpellDemos.java b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/SpellDemos.java
new file mode 100644
index 0000000..d415aba
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util.tests/src/org/eclipse/uomo/util/test/numbers/SpellDemos.java
@@ -0,0 +1,458 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.test.numbers;
+
+/**
+ * Maximum value to handle : 9223372036854775807
+ * (9,223,372,036,854,775,807) Nine Quintillion, Two Hundred and
+ * Twenty-Three Quadrillion, Three Hundred and Seventy-Two Trillion,
+ * Thirty-Six Billion, Eight Hundred and Fifty-Four Million, Seven
+ * Hundred and Seventy-Five Thousand, Eight Hundred and Seven
+ * 
+ * Thanks to 911 Programming
+ */
+
+import java.io.IOException;
+import java.util.Scanner;
+
+import org.eclipse.uomo.util.numbers.SpellException;
+import org.eclipse.uomo.util.numbers.impl.SpellContext;
+
+/**
+ * A multiple demo program to test SpellContext class.
+ * 
+ * @author Werner Keil
+ * 
+ */
+public class SpellDemos {
+
+	/**
+	 * The main program of this demo runs five demos one after the other with a
+	 * pause between each two of them.
+	 * 
+	 * @param args
+	 *            Not used in this demo.
+	 */
+	public static void main(String[] args) {
+
+		/*
+		 * Enables or disables formal hyphen in cent-digit combination like
+		 * 'Forty-Five' or 'Forty Five'.
+		 */
+		SpellContext.usingCentHyphen = true;
+
+		// to disable pause between outputs, set the following variable to
+		// false.
+		pauseBetweenOutputs = false;
+
+		// Print Introduction:
+		System.out.println("Spelling Number Test Console  0.6");
+		System.out
+				.println("A Java demo to spell numbers and to parse spelled number text.");
+		System.out.println("Version 0.6");
+		System.out.println("Eclipse Foundation.");
+
+		// Run demos one after the other. Pause between them.
+		pause("Demo One - Testing Auto-Generated Numbers");
+		demoOne();
+		pause("Demo Two - Testing Auto-Generated Numbers");
+		demoTwo();
+		pause("Demo Three - Testing Auto-Generated Numbers");
+		demoThree();
+		pause("Demo Max - Testing Maximum Long Value");
+		demoMax();
+		pause("Demo Four - Interactive user mode");
+		demoFour();
+	}
+
+	/**
+	 * This variable enables or disables extra pauses within each
+	 * non-interactive demos.
+	 */
+	private static boolean pauseBetweenOutputs = false;
+
+	/**
+	 * Pause used within each demo.
+	 */
+	private static void pause() {
+		if (pauseBetweenOutputs) {
+
+			System.out.print("\nPress <RETURN> to continue");
+			try {
+				while (System.in.read() != '\r')
+					;
+			} catch (IOException e) {
+				// Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Pause used between demos with an introductory caption.
+	 * 
+	 * @param message
+	 *            The caption of pause.
+	 */
+	private static void pause(String message) {
+		System.out.printf("\nPress <RETURN> to prceed to the next step : %1$s",
+				message);
+		try {
+			while (System.in.read() != '\r')
+				;
+		} catch (IOException e) {
+			// Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Demo One : Tests some automatically generated numbers.
+	 */
+	private static void demoOne() {
+		System.out.println("\n\n----  ----  ----  ----  ----  ----  ");
+		System.out.println("Demo One - Auto-Generated Numbers (1)");
+
+		long value = 0L;
+		for (long i = 0; i <= 10L; i++) {
+			value = value * 10 + i;
+			dump(value);
+			pause();
+		}
+	}
+
+	/**
+	 * Demo Two : Tests some automatically generated numbers.
+	 */
+	private static void demoTwo() {
+		System.out.println("\n\n----  ----  ----  ----  ----  ----  ");
+		System.out.println("Demo Two - Auto-Generated Numbers (2)");
+
+		for (int i = 0; i < 20; i++) {
+			dump(i * 10000 + i);
+			pause();
+		}
+
+	}
+
+	/**
+	 * Demo Three : Tests some automatically generated numbers.
+	 */
+	private static void demoThree() {
+		System.out.println("\n\n----  ----  ----  ----  ----  ----  ");
+		System.out.println("Demo Three - Auto-Generated Numbers (3)");
+
+		long value;
+		value = 0L;
+
+		for (long i = 32; i >= 0L; i--) {
+			value = value * 10 + i;
+			dump(value);
+			pause();
+		}
+	}
+
+	/**
+	 * Demo Four : The interactive user mode. It gets a numeric value or spelled
+	 * number text from user. If it is a numeric value, it spells it. If it is a
+	 * spelled text, it parses the text and displays its equivalent numeric
+	 * value. All works are displayed in the same format. This demo checks if
+	 * the grammar associated with the spelled number entered by user is correct
+	 * or not, and if it is not, it prints the formal correct spelling of the
+	 * perceived number.
+	 * 
+	 * @see {@link #dump(long)}, {@link #dump(String)},
+	 *      {@link #dump(long, String)} and
+	 *      {@link SpellDemos#DumpSpellText(String)}
+	 */
+	private static void demoFour() {
+		System.out.println("\n\n----  ----  ----  ----  ----  ----  ");
+		System.out.println("Demo Four - User Interactive Mode\n");
+
+		// create a scanner for std input (keyboard input).
+		Scanner in = new Scanner(System.in);
+		in.nextLine();
+
+		// lineToProcess keeps the user input text. It is specially used for
+		// multi-line text input.
+		String lineToProcess = null;
+
+		for (;;) {
+			// print prompt only if it is not (still) a multi-line input.
+			if (lineToProcess == null) {
+				System.out
+						.println("Enter 'numeric value' or 'spelled number text' :");
+				System.out
+						.println("(Type '.' to terminate the loop, type '\\' to continue the text at next line)");
+			}
+
+			// read next line as text.
+			String lineText = in.nextLine();
+
+			// Check if it is a single dot (.)
+			if (lineText.equals(".")) {
+				// if it is, check if there is some text still to be processed,
+				if (lineToProcess != null) {
+					try {
+						// if it is, dump the line.
+						dump(lineToProcess);
+					} catch (Exception e) {
+						// check errors.
+						System.err.println("\n\n" + e.getMessage() + "\n\n");
+					}
+				}
+				// break to terminate the demo.
+				break;
+			} else if (lineText.equals(""))
+				// otherwise, If it is an empty line, ignore it.
+				continue;
+
+			// If it is not either a dot (.) or an empty line, check data.
+
+			// Check if there is some previous unprocessed text,
+			if (lineToProcess == null)
+				// if it is not, set it as a fresh text.
+				lineToProcess = lineText.replaceAll("\\\\", "");
+			else
+				// Otherwise, append this line to that (for non-numeric spelled
+				// number text only).
+				lineToProcess += " " + lineText.replaceAll("\\\\", "");
+
+			// If this line is not marked to be continued,
+			if (!lineText.endsWith("\\")) {
+				// process it:
+				try {
+					// dump the line of text.
+					dump(lineToProcess);
+
+				} catch (Exception e) {
+
+					// Report error is there is any.
+					System.err.println("\n\n" + e.getMessage() + "\n\n");
+
+				} finally {
+					// mark the line to be processed as fresh.
+					lineToProcess = null;
+
+				}
+
+			}
+		}
+
+		// close the scanner.
+		in.close();
+	}
+
+	/**
+	 * Demo Max : Tests the maximum number to handle.
+	 */
+	private static void demoMax() {
+		System.out.println("\n\n----  ----  ----  ----  ----  ----  ");
+		System.out.println("Demo Max - Testing Maximum Value");
+
+		System.out.println("\nMaximim value to handle : " + Long.MAX_VALUE);
+		dump(Long.MAX_VALUE);
+		System.out.println();
+	}
+
+	/**
+	 * Dump the data based on the numeric value.
+	 * 
+	 * @param value
+	 *            The numeric value to dump
+	 * 
+	 * @see {@link #dump(long, String)} dump the number data based on its
+	 *      numeric value or spelled text.
+	 */
+	private static void dump(long value) {
+		dump(value, null);
+	}
+
+	/**
+	 * Dump the data based on the spelled text or numeric value represented as
+	 * text String format.
+	 * 
+	 * @param line
+	 *            The text string containing the spelled number or numeric
+	 *            value.
+	 * 
+	 * @see {@link #dump(long, String)} dump the number data based on its
+	 *      numeric value or spelled text.
+	 */
+	private static void dump(String line) {
+		long value;
+
+		try {
+			// first try to dump it as number.
+			value = Long.parseLong(line.replaceAll(",", ""));
+			dump(value, null);
+
+		} catch (NumberFormatException e) {
+			// If not successful, try it as text.
+			dump(0, line);
+		}
+	}
+
+	/**
+	 * Dump the data based on the spelled text (if not null), otherwise, based
+	 * on the numeric value. This is the most basic method which actually tests
+	 * the SpellContext class.
+	 * 
+	 * @param value
+	 *            If spellText is null, this is the numeric value to dump.
+	 * @param spellText
+	 *            If not null, it is the spelled number text to dump.
+	 * 
+	 * @see {@link #DumpSpellText(String)} to check how spelled text is nicely
+	 *      formatted, possibly in multi-lines.
+	 */
+	private static void dump(long value, String spellText) {
+
+		// assume user-spelled format which might need correction.
+		boolean userSpelledText = true;
+
+		// decide which one to choose : the numeric value or spelled text.
+		// if spellText is null, assume numeric value, otherwise, assume spelled
+		// text.
+		if (spellText == null) {
+			// Report to user that it is a numeric value to dump.
+			System.out.printf("%1$d (Numeric)\n", value);
+			try {
+				// create the spelled text from the numeric value.
+				spellText = SpellContext.of().spell(value);
+				// There is no need for formal spelled text because the spelled
+				// text is generated from this program (not user), and it does
+				// not contain any spelling error.
+				userSpelledText = false;
+			} catch (SpellException e) {
+				e.printStackTrace();
+			}
+		} else {
+			// Otherwise, report to user that it is a spelled number to dump.
+			System.out.println("(Spelled Number)");
+		}
+
+		// Now, spellText is the basis of the data dump.
+
+		try {
+			// If it is user spelled text, evaluate the corresponding value.
+			if (userSpelledText)
+				value = SpellContext.of().parse(spellText);
+
+			// encode the spelled text
+			String encoded = SpellContext.encode(spellText);
+			// decode the encoded text.
+			String decoded = SpellContext.decode(encoded);
+
+			// first, assume that the spelling is correct.
+			boolean spellIsCorrect = true;
+
+			try {
+				// validate the spelling.
+				SpellContext.of().validate(encoded);
+
+			} catch (SpellException e) {
+				// mark incorrect, if validation failed.
+				spellIsCorrect = false;
+			}
+
+			// The dump table :
+
+			// The numeric value
+			System.out.printf("\tNumeric Value : %1$s\n",
+					SpellContext.withSeparator(value));
+
+			// The spell text
+			DumpSpellText(spellText);
+
+			// Decide if it is a user spelled text and needs a formal spelled
+			// text to compare.
+			if (userSpelledText) {
+				String formalSpell = SpellContext.of().spell(value);
+				String formalEncode = SpellContext.encode(formalSpell);
+
+				if (!formalEncode.equals(encoded)) {
+					System.out.println("\tFormal Spell: ");
+					DumpSpellText(formalSpell);
+				}
+			}
+
+			// The encoded text:
+			System.out.println("\tEncoded : " + encoded);
+
+			// The decoded text to compare to the original spelled text.
+			System.out.println("\tDecoded : ");
+			DumpSpellText(decoded);
+
+			// if user spelled text, check if it is correct or not.
+			if (userSpelledText)
+				System.out.println("\tSpelling : "
+						+ (spellIsCorrect ? "Correct" : "Incorrect"));
+
+			System.out.println();
+
+		} catch (SpellException e) {
+			// report spell error if any.
+			System.err.println("\n\n" + e.getMessage() + "\n\n");
+		} catch (Exception e) {
+			// report general error if any.
+			System.err.println("\n\n" + e.getMessage() + "\n\n");
+		}
+	}
+
+	/**
+	 * Prints the spelled text in nice width-limited format.
+	 * 
+	 * @param spellText
+	 *            The spelled text.
+	 */
+	private static void DumpSpellText(String spellText) {
+		String[] tokens = spellText.split("\\s+");
+
+		// set it as the first column
+		int columnIndex = 0;
+
+		// The space chars between words.
+		final String space = "  ";
+
+		// the number of spaces between word.
+		final int spaceCount = space.length();
+
+		// prefix the first line with two tabs.
+		System.out.print("\t\t");
+
+		// for each word of the spelled text,
+		for (String token : tokens) {
+			// if it goes beyond the line width limit,
+			if (columnIndex + token.length() + spaceCount > 80) {
+				// go to the next line,
+				System.out.println();
+				// prefix the line with two tabs.
+				System.out.print("\t\t");
+				// set it as the first column.
+				columnIndex = 0;
+			}
+
+			// if it is not the first word of the line, print word separator.
+			if (columnIndex > 0)
+				System.out.print(space);
+
+			// Now, print the word itself.
+			System.out.print(token);
+
+			// update column index;
+			columnIndex += token.length();
+		}
+
+		// print a line-separator.
+		System.out.println();
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/.classpath b/bundles/org.eclipse.uomo.util/.classpath
new file mode 100644
index 0000000..47ca448
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="src" path="src/main/resources/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.util/.gitignore b/bundles/org.eclipse.uomo.util/.gitignore
new file mode 100644
index 0000000..2c36b17
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/.gitignore
@@ -0,0 +1,2 @@
+/target
+/.settings
diff --git a/bundles/org.eclipse.uomo.util/.project b/bundles/org.eclipse.uomo.util/.project
new file mode 100644
index 0000000..1b0a938
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/.project
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.util</name>
+	<comment>UOMo adds Units of Measurement support for IT Systems and Services both to Language and Data. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.util/.springBeans b/bundles/org.eclipse.uomo.util/.springBeans
new file mode 100644
index 0000000..6c6cb5a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.5.0.201010221000-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.util/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.util/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..53f6e2a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.util
+Bundle-SymbolicName: org.eclipse.uomo.util;singleton:=true
+Bundle-Version: 0.6.0.qualifier
+Bundle-Activator: org.eclipse.uomo.util.internal.UtilitiesPlugin
+Bundle-Vendor: Eclipse OSBP
+Export-Package: org.eclipse.uomo.util,
+ org.eclipse.uomo.util.impl,
+ org.eclipse.uomo.util.numbers
+Require-Bundle: org.eclipse.uomo.core;bundle-version="0.2.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.apache.commons.lang;bundle-version="2.3.0",
+ org.junit;bundle-version="4.8.2"
+Import-Package: org.eclipse.uomo.util
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/bundles/org.eclipse.uomo.util/about.html b/bundles/org.eclipse.uomo.util/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/build.properties b/bundles/org.eclipse.uomo.util/build.properties
new file mode 100644
index 0000000..f6e1e45
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#    Jiva Medical - initial API and implementation
+###############################################################################
+source.. = src/main/java/, src/main/resources/
+output.. = target/classes/
+bin.includes = .,\
+               META-INF/
diff --git a/bundles/org.eclipse.uomo.util/pom.xml b/bundles/org.eclipse.uomo.util/pom.xml
new file mode 100644
index 0000000..5d554ff
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/pom.xml
@@ -0,0 +1,91 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.util</artifactId>
+	<name>UOMo Utilities</name>
+	<packaging>eclipse-plugin</packaging>
+	
+	<!-- ======================================================= -->
+    <!-- Build Settings -->
+    <!-- ======================================================= -->
+    <build>
+        <plugins>
+            <!-- ======================================================= -->
+            <!-- Compilation -->
+            <!-- ======================================================= -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+                <configuration>
+                    <source>${project.build.javaVersion}</source>
+					<target>${project.build.javaVersion}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            
+            <!-- ======================================================= -->
+            <!-- Packaging -->
+            <!-- ======================================================= -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.2</version>
+                  <executions>
+		         <execution>
+		           <goals>
+		             <goal>test-jar</goal>
+		           </goals>
+		         </execution>
+      			 </executions>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Implementation-Title>${project.name}</Implementation-Title>
+                            <Implementation-Version>${project.version}
+                            </Implementation-Version>
+                            <!-- mode>development</mode> TODO call it stage? <SCM-Revision>${buildNumber}</SCM-Revision -->
+                            <SCM-Revision>$Revision: 205 $</SCM-Revision>
+                        </manifestEntries>
+                        <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            
+            <!-- ======================================================= -->
+            <!-- Packaging (OSGi bundle) -->
+            <!-- ======================================================= -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.2.0</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>org.eclipse.uomo.util.*</Export-Package>
+                        <Private-Package>!*</Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+    <!-- ==================================================== -->
+    <!-- Repositories. This is where Maven looks for dependencies. The Maven 
+        repository is implicit and doesn't need to be specified. -->
+    <!-- ==================================================== -->
+<!--     <repositories>         -->
+<!--         <repository> -->
+<!--             <id>jboss</id> -->
+<!--             <name>JBoss Repository</name> -->
+<!--             <url>http://repository.jboss.org/maven2</url>             -->
+<!--         </repository> -->
+<!--     </repositories> -->
+	
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Dictionary.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Dictionary.java
new file mode 100644
index 0000000..675493b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Dictionary.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util;
+
+/**
+ * @author Werner Keil
+ * OSGi demo.
+ * 
+ * @deprecated change this into something more useful for UOM, e.g. Conversion
+ */
+public interface Dictionary {
+	
+    /**
+     * Returns the language of the dictionary
+     *
+     * @return the language of the dictionary
+     */
+    public String getLanguage();
+	
+    /**
+     * Check for the existence of a word in the dictionary
+     * 
+     * @param word the word to be checked.
+     * @return true if the word is in the dictionary
+     */
+    public boolean check(String word);
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/DictionaryService.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/DictionaryService.java
new file mode 100644
index 0000000..d7165b0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/DictionaryService.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2005, 2010, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util;
+
+/**
+ * @author Werner Keil
+ * OSGi demo.
+ * 
+ * @deprecated change this into something more useful for UOM, e.g. ConversionService
+ */
+public interface DictionaryService {
+	
+    /**
+     * Register a dictionary
+     * 
+     * @param dictionary the dictionary to be added.
+     */
+    public void registerDictionary(Dictionary dictionary);
+    
+    /**
+     * Remove a dictionary
+     * 
+     * @param dictionary the dictionary to be removed.
+     */
+    public void unregisterDictionary(Dictionary dictionary);
+	
+    /**
+     * Check for the existence of a word across all dictionaries
+     * 
+     * @param word the word to be checked.
+     * @return true if the word is in any dictionary
+     */
+    public boolean check(String word);
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Generator.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Generator.java
new file mode 100644
index 0000000..91fc5bc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Generator.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util;
+
+import org.eclipse.uomo.core.UOMoException;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ *
+ * @param <M> the model
+ * @param <O> the output
+ */
+public interface Generator<M, O> {
+	public O generate(M model) throws UOMoException;
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Parser.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Parser.java
new file mode 100644
index 0000000..0db3aec
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Parser.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2011, 2013 Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util;
+
+import org.eclipse.uomo.core.UOMoException;
+
+/**
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ *
+ * @param <I> the input
+ * @param <O> the output
+ */
+public interface Parser<I, O> {
+	public O parse(I input) throws UOMoException;
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Registry.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Registry.java
new file mode 100644
index 0000000..b505f26
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/Registry.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util;
+
+/**
+ * @author  <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * 
+ * @param <V> the type of mapped values
+ */
+public interface Registry<V> {
+	public boolean exists(String key);
+
+	public V get(String key);	
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryImpl.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryImpl.java
new file mode 100644
index 0000000..2ab994e
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryImpl.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil and others - initial API and implementation
+ */
+package org.eclipse.uomo.util.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.uomo.util.Dictionary;
+
+@SuppressWarnings("deprecation")
+public class DictionaryImpl implements Dictionary {
+
+	private List<String> fWords = new ArrayList<String>(
+			Arrays.asList(new String[] { "osgi", "eclipse", "ucum" }));
+	private String fLanguage = "English";
+
+	public String getLanguage() {
+		return fLanguage;
+	}
+
+	public boolean check(String word) {
+		return fWords.contains(word);
+	}
+
+	public String toString() {
+		return fLanguage;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryServiceImpl.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryServiceImpl.java
new file mode 100644
index 0000000..f44dd24
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/DictionaryServiceImpl.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil and others - initial API and implementation
+ */
+package org.eclipse.uomo.util.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.util.Dictionary;
+import org.eclipse.uomo.util.DictionaryService;
+
+public class DictionaryServiceImpl implements DictionaryService {
+
+	private final List<Dictionary> fDictionaries = new ArrayList<Dictionary>();
+
+	public void registerDictionary(Dictionary dictionary) {
+		fDictionaries.add(dictionary);
+	}
+
+	public void unregisterDictionary(Dictionary dictionary) {
+		fDictionaries.remove(dictionary);
+	}
+
+	public boolean check(String word) {
+		for (int i = 0; i < fDictionaries.size(); i++) {
+			Dictionary dictionary = (Dictionary) fDictionaries.get(i);
+			if (dictionary.check(word))
+				return true;
+		}
+		return false;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/Iso8601Date.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/Iso8601Date.java
new file mode 100644
index 0000000..2a2e449
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/impl/Iso8601Date.java
@@ -0,0 +1,1065 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.util.impl;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.util.internal.Messages;
+
+/**
+ * ISO 8601 Dates
+ * 
+ * HL7 uses a date format which is conforms to the constrained ISO 8601 that is
+ * defined in ISO 8824 (ASN.1) under clause 32 (generalized time).
+ * 
+ * Because of the ubiquity of HL7 interfaces, and the general utility of this
+ * time format representation, it's encountered fairly often in healthcare
+ * 
+ * This Date class represents the notion of a date time that may have years,
+ * months, days, hours, minutes, seconds, milliseconds and timezones specified.
+ * 
+ * There is three ways to interact with this date - read and write the component
+ * fields directly - read and write the string form using parse() and render() -
+ * get and set the time as a java Date object using getAsDate and setAsDate
+ * 
+ * It's possible to set the component fields to non-sensical values. Use
+ * validate() to check whether the values are okay.
+ * 
+ * Note about parsing:
+ * 
+ * There is several entry points to the parser. The simplest takes only the
+ * actual string to parse. If the string is a proper value according to the
+ * specifications referenced above, it will be read in.
+ * 
+ * In addition, there is another entry point that allows the caller to specify a
+ * mask that describes what parts of the date are required, and what is allowed,
+ * Consult the ISO_DATE_VALIDATION_FULL constant for an example of how to use
+ * the mask. In addition, the caller can specify what to do with the timezone
+ * 
+ * Finally, there is a static routine that takes the same parameters and returns
+ * a date or throws an exception
+ * 
+ */
+public class Iso8601Date {
+
+	// public constants FIXME change to enum values
+	/**
+	 * timezone information will be ignored
+	 */
+	public static final int IGNORE = 0;
+	/**
+	 * timezone is required
+	 */
+	public static final int REQUIRED = 1;
+	/**
+	 * timezone is optional
+	 */
+	public static final int OPTIONAL = 2;
+	/**
+	 * timezone is prohibited
+	 */
+	public static final int PROHIBITED = 3;
+	/**
+	 * parsing: timezone information will be cleared
+	 */
+	public static final int CLEAR = 4;
+	/**
+	 * timezone information will be set to local value
+	 */
+	public static final int SETLOCAL = 5;
+	/**
+	 * use timezone information if specified
+	 */
+	public static final int IF_PRESENT = 6;
+	/**
+	 * parsing mask for a fully optional date other than the year, which is
+	 * required
+	 */
+	public static final String ISO_DATE_VALIDATION_FULL = Messages.Iso8601Date_ISO_DATE_VALIDATION_FULL;
+	/**
+	 * just the date, with optional month and day
+	 */
+	public static final String ISO_DATE_VALIDATION_DATE = Messages.Iso8601Date_ISO_DATE_VALIDATION_DATE;
+	/**
+	 * default format for writing
+	 */
+	public static final String DEF_OUTPUT_FORMAT = Messages.Iso8601Date_DEF_OUTPUT_FORMAT;
+
+	// private fields
+
+	private int year;
+	private int month;
+	private int day;
+	private int hour;
+	private int minute;
+	private int second;
+	private int milli;
+	private int tzHour;
+	private int tzMinute;
+	private Boolean tzNegative = null; // null means no timezone specified
+
+	// administration
+	public Iso8601Date() {
+		super();
+		reset(true);
+	}
+
+	private void reset(boolean timezoneToo) {
+		year = -1;
+		month = -1;
+		day = -1;
+		hour = -1;
+		minute = -1;
+		second = -1;
+		milli = -1;
+		if (timezoneToo) {
+			tzHour = 0;
+			tzMinute = 0;
+			tzNegative = null;
+		}
+	}
+
+	/**
+	 * 
+	 * @return a string describing any errors with the component field values
+	 */
+	public String validate(boolean checkYearReasonable) {
+		StringBuffer s = new StringBuffer();
+
+		// TODO use Units where possible
+		boolean content = false;
+		content = checkField(s, milli, content, 0, 999,
+				Messages.Iso8601Date_MILIS);
+		content = checkField(s, second, content, 0, 59,
+				Messages.Iso8601Date_SECONDS);
+		content = checkField(s, minute, content, 0, 59,
+				Messages.Iso8601Date_MINUTES);
+		content = checkField(s, hour, content, 0, 23,
+				Messages.Iso8601Date_HOURS);
+		content = checkField(s, day, content, 1, 31, Messages.Iso8601Date_DAYS);
+		content = checkField(s, month, content, 1, 12,
+				Messages.Iso8601Date_MONTHS);
+		if (checkYearReasonable)
+			content = checkField(s, year, content, 1000, 2500,
+					Messages.Iso8601Date_YEARS);
+		else
+			content = checkField(s, year, content, Integer.MIN_VALUE,
+					Integer.MAX_VALUE, "years"); //$NON-NLS-1$
+
+		if (!content)
+			s.append(Messages.Iso8601Date_NO_VALUES_SET);
+
+		if (year != -1 && month != -1 && day != -1
+				&& day > daysForMonth(month, year))
+			s.append(Messages.Iso8601Date_THE_DAY
+					+ Integer.toString(day)
+					+ " is not valid for the month " + Integer.toString(month) + " in the year " + Integer.toString(year) + "\r\n"); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+		if (tzNegative != null) {
+			content = checkField(s, tzMinute, content, 0, 59,
+					Messages.Iso8601Date_TZ_MINUTES);
+			content = checkField(s, tzHour, content, 0, 13,
+					Messages.Iso8601Date_TZ_HOURS);
+		}
+		if (s.length() > 0)
+			return s.toString();
+		else
+			return null;
+	};
+
+	private boolean checkField(StringBuffer s, int value, boolean required,
+			int min, int max, String desc) {
+		if (value == -1) {
+			if (required)
+				s.append(Messages.Iso8601Date_VALUE_MISSING + desc
+						+ " is missing and required in this context"); //$NON-NLS-2$
+			return required;
+		} else {
+			if (value < min || value > max)
+				s.append(Messages.Iso8601Date_VALUE_INVALID
+						+ desc
+						+ " is invalid (is " + Integer.toString(value) + " should be " + Integer.toString(min) + " - " + Integer.toString(max) + ")"); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+			return true;
+		}
+	}
+
+	// component field access
+
+	/**
+	 * @return the year. -1 means not set
+	 */
+	public int getYear() {
+		return year;
+	}
+
+	/**
+	 * @param year
+	 *            the year to set. -1 means not set
+	 */
+	public void setYear(int year) {
+		this.year = year;
+	}
+
+	/**
+	 * @return the month. -1 means not set
+	 */
+	public int getMonth() {
+		return month;
+	}
+
+	/**
+	 * @param month
+	 *            the month to set. -1 means not set
+	 */
+	public void setMonth(int month) {
+		this.month = month;
+	}
+
+	/**
+	 * @return the day. -1 means not set
+	 */
+	public int getDay() {
+		return day;
+	}
+
+	/**
+	 * @param day
+	 *            the day to set. -1 means not set
+	 */
+	public void setDay(int day) {
+		this.day = day;
+	}
+
+	/**
+	 * @return the hour. -1 means not set
+	 */
+	public int getHour() {
+		return hour;
+	}
+
+	/**
+	 * @param hour
+	 *            the hour to set. -1 means not set
+	 */
+	public void setHour(int hour) {
+		this.hour = hour;
+	}
+
+	/**
+	 * @return the minute. -1 means not set
+	 */
+	public int getMinute() {
+		return minute;
+	}
+
+	/**
+	 * @param minute
+	 *            the minute to set. -1 means not set
+	 */
+	public void setMinute(int minute) {
+		this.minute = minute;
+	}
+
+	/**
+	 * @return the second. -1 means not set
+	 */
+	public int getSecond() {
+		return second;
+	}
+
+	/**
+	 * @param second
+	 *            the second to set. -1 means not set
+	 */
+	public void setSecond(int second) {
+		this.second = second;
+	}
+
+	/**
+	 * @return the milliseconds. -1 means not set
+	 */
+	public int getMilli() {
+		return milli;
+	}
+
+	/**
+	 * @param milli
+	 *            the milliseconds to set. -1 means not set
+	 */
+	public void setMilli(int milli) {
+		this.milli = milli;
+	}
+
+	/**
+	 * @return the timezone Hour. use tzNegative to see whether timezone is set
+	 */
+	public int getTzHour() {
+		return tzHour;
+	}
+
+	/**
+	 * @param tzHour
+	 *            the timezone Hour to set. use tzNegative to see whether
+	 *            timezone is set
+	 */
+	public void setTzHour(int tzHour) {
+		this.tzHour = tzHour;
+	}
+
+	/**
+	 * @return the timezone Minute. use tzNegative to see whether timezone is
+	 *         set
+	 */
+	public int getTzMinute() {
+		return tzMinute;
+	}
+
+	/**
+	 * @param tzMinute
+	 *            the timezone Minute to set. use tzNegative to see whether
+	 *            timezone is set
+	 */
+	public void setTzMinute(int tzMinute) {
+		this.tzMinute = tzMinute;
+	}
+
+	/**
+	 * @return the tzNegative - true if the timezone is negative, false it it's
+	 *         positive, and null if there's no timezone info
+	 */
+	public Boolean getTzNegative() {
+		return tzNegative;
+	}
+
+	/**
+	 * @param tzNegative
+	 *            the tzNegative to set - true if the timezone is negative,
+	 *            false it it's positive, and null if there's no timezone info
+	 */
+	public void setTzNegative(Boolean tzNegative) {
+		this.tzNegative = tzNegative;
+	}
+
+	// Utilities
+	public Iso8601Date correctForTZ() {
+		Iso8601Date result = new Iso8601Date();
+		result.year = year;
+		result.month = month;
+		result.day = day;
+		result.hour = hour;
+		result.minute = minute;
+		result.second = second;
+		result.milli = milli;
+
+		if (tzNegative != null) {
+			if (tzNegative.booleanValue()) {
+				result.addMin(-(tzHour * 60 + tzMinute));
+			} else {
+				result.addMin((tzHour * 60 + tzMinute));
+			}
+		}
+		return result;
+	}
+
+	// TODO: remove if nolonger used
+	// private void addSec(int i) {
+	// if (i != 0) {
+	// if (second == -1)
+	// addMin(i / 60);
+	// else {
+	// second = second + i;
+	// int min = 0;
+	// while (second < 0) {
+	// second = second + 60;
+	// min = min - 1;
+	// }
+	// while (second >= 60) {
+	// second = second - 60;
+	// min = min + 1;
+	// }
+	// addMin(min);
+	// }
+	// }
+	// }
+
+	private void addMin(int i) {
+		if (i != 0) {
+			if (minute == -1)
+				addHour(i / 60);
+			else {
+				minute = minute + i;
+				int hr = 0;
+				while (minute < 0) {
+					minute = minute + 60;
+					hr = hr - 1;
+				}
+				while (minute >= 60) {
+					minute = minute - 60;
+					hr = hr + 1;
+				}
+				addHour(hr);
+			}
+		}
+	}
+
+	private void addHour(int i) {
+		if (i != 0) {
+			if (hour == -1)
+				addDay(i / 24);
+			else {
+				hour = hour + i;
+				int d = 0;
+				while (hour < 0) {
+					hour = hour + 24;
+					d = d - 1;
+				}
+				while (hour >= 24) {
+					hour = hour - 24;
+					d = d + 1;
+				}
+				addDay(d);
+			}
+		}
+	}
+
+	private void addDay(int i) {
+		if (i != 0 && day != -1) {
+			day = day + i;
+			while (day < 1 || day > daysForMonth(month, year)) {
+				if (day < 1) {
+					day = day + daysForMonth(month, year);
+					month = month - 1;
+					if (month == 0) {
+						month = 12;
+						year = year - 1;
+					}
+				}
+
+				if (day > daysForMonth(month, year)) {
+					month = month + 1;
+					if (month == 13) {
+						month = 1;
+						year = year + 1;
+					}
+					day = day - daysForMonth(month, year);
+				}
+			}
+		}
+	}
+
+	// Date access
+
+	/**
+	 * get the date specified as a Date.
+	 * 
+	 * @param timezone
+	 *            - REQUIRED, IF_PRESENT or IGNORE
+	 * @throws OHFException
+	 */
+	public Date getAsDate(int timezone) throws UOMoException {
+		GregorianCalendar cal = new GregorianCalendar();
+		cal.clear();
+		if (year != -1)
+			cal.set(Calendar.YEAR, year);
+		if (month != -1)
+			cal.set(Calendar.MONTH, month - 1); // Calendar month start with 0
+		if (day != -1)
+			cal.set(Calendar.DAY_OF_MONTH, day);
+		if (hour != -1)
+			cal.set(Calendar.HOUR_OF_DAY, hour);
+		if (minute != -1)
+			cal.set(Calendar.MINUTE, minute);
+		if (second != -1)
+			cal.set(Calendar.SECOND, second);
+		if (milli != -1)
+			cal.set(Calendar.MILLISECOND, milli);
+
+		if (timezone == REQUIRED || timezone == IF_PRESENT
+				|| timezone == OPTIONAL) {
+			if (timezone == REQUIRED && tzNegative == null)
+				throw new UOMoException(Messages.Iso8601Date_TZ_NOT_DEFINED);
+			if (tzNegative != null) {
+				TimeZone tzMsg = TimeZone.getTimeZone(Messages.Iso8601Date_GMT
+						+ prepTimezone());
+				cal.setTimeZone(tzMsg);
+			}
+		}
+		return cal.getTime();
+	}
+
+	/**
+	 * 
+	 * @param date
+	 *            the date to set the component fields to
+	 * @param timezone
+	 *            - what to do about timezone (CLEAR, SETLOCAL or IGNORE)
+	 */
+	public void setAsDate(Date date, int timezone) {
+		GregorianCalendar cal = new GregorianCalendar();
+		cal.setTime(date);
+		reset(timezone != IGNORE);
+		year = cal.get(Calendar.YEAR);
+		month = cal.get(Calendar.MONTH) + 1; // java Month starts from 0, but
+												// ours starts from 1
+		day = cal.get(Calendar.DAY_OF_MONTH);
+		hour = cal.get(Calendar.HOUR_OF_DAY);
+		minute = cal.get(Calendar.MINUTE);
+		second = cal.get(Calendar.SECOND);
+		milli = cal.get(Calendar.MILLISECOND);
+
+		if (timezone == CLEAR) {
+			tzHour = 0;
+			tzMinute = 0;
+			tzNegative = null;
+		} else if (timezone == SETLOCAL) {
+			TimeZone tzLcl = TimeZone.getDefault();
+			int offset = tzLcl.getOffset(date.getTime());
+			if (offset < 0) {
+				tzNegative = new Boolean(true);
+				offset = -offset;
+			} else {
+				tzNegative = new Boolean(true);
+			}
+			tzHour = offset / (1000 * 60 * 60);
+			tzMinute = (offset - (tzHour * 1000 * 60 * 60)) / (1000 * 60);
+		}
+	}
+
+	// String format
+
+	/**
+	 * get the date as a formatted string
+	 * 
+	 * @param format
+	 *            - the format to use. Must be consistent with the components
+	 *            provided. Will be cross-checked
+	 * @param timezone
+	 *            - what to do about timezone (REQUIRED, IF_PRESENT, PROHIBITED,
+	 *            IGNORE)
+	 * @return
+	 * @throws OHFException
+	 *             if cross check fails
+	 */
+	public String render(String format, boolean checkValues, int timezone)
+			throws UOMoException {
+
+		String v = validate(false);
+		if (v != null)
+			throw new UOMoException(v);
+
+		StringBuffer str = new StringBuffer();
+		render(str,
+				checkValues,
+				format.length() >= 4
+						&& Messages.Iso8601Date_yyyy.equalsIgnoreCase(format
+								.substring(0, 4)), 4, year, format,
+				Messages.Iso8601Date_year, null);
+		render(str,
+				checkValues,
+				format.length() >= 6
+						&& Messages.Iso8601Date_mm.equalsIgnoreCase(format
+								.substring(4, 6)), 2, month, format,
+				Messages.Iso8601Date_month, null);
+		render(str,
+				checkValues,
+				format.length() >= 8
+						&& Messages.Iso8601Date_dd.equalsIgnoreCase(format
+								.substring(6, 8)), 2, day, format,
+				Messages.Iso8601Date_day, null);
+		render(str,
+				checkValues,
+				format.length() >= 10
+						&& Messages.Iso8601Date_hh.equalsIgnoreCase(format
+								.substring(8, 10)), 2, hour, format,
+				Messages.Iso8601Date_hour, null);
+		render(str,
+				checkValues,
+				format.length() >= 12
+						&& Messages.Iso8601Date_nn.equalsIgnoreCase(format
+								.substring(10, 12)), 2, minute, format,
+				Messages.Iso8601Date_minute, null);
+		render(str,
+				checkValues,
+				format.length() >= 14
+						&& Messages.Iso8601Date_ss.equalsIgnoreCase(format
+								.substring(12, 14)), 2, second, format,
+				Messages.Iso8601Date_second, null);
+
+		if (format.length() >= 18
+				&& Messages.Iso8601Date_sss.equalsIgnoreCase(format.substring(
+						15, 18))) {
+			render(str, checkValues, true, 3, milli, format,
+					Messages.Iso8601Date_milisecond, Messages.Iso8601Date_DOT);
+		} else if (format.length() == 17
+				&& "ss".equalsIgnoreCase(format.substring(15, 17))) { //$NON-NLS-1$
+			render(str, checkValues, true, 2, milli / 10, format,
+					"millisecond", Messages.Iso8601Date_DOT); //$NON-NLS-1$
+		} else if (format.length() == 16
+				&& Messages.Iso8601Date_s.equalsIgnoreCase(format.substring(15,
+						16))) {
+			render(str, checkValues, true, 1, milli / 100, format,
+					"millisecond", "."); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		if (timezone == REQUIRED || timezone == IF_PRESENT) {
+			if (timezone == REQUIRED && tzNegative == null)
+				throw new UOMoException(
+						Messages.Iso8601Date_TZ_REQUIRED_BUT_NOT_DEFINED);
+			if (tzNegative != null) {
+				if (tzNegative.booleanValue())
+					str.append('-');
+				else
+					str.append('+');
+				render(str, checkValues, true, 2, tzHour, format,
+						Messages.Iso8601Date_tz_hour, null);
+				render(str, checkValues, true, 2, tzMinute, format,
+						Messages.Iso8601Date_tz_minutes, null);
+			}
+		}
+		if (timezone == PROHIBITED && tzNegative != null)
+			throw new UOMoException(
+					Messages.Iso8601Date_TZ_PROHIBITED_BUT_DEFINED);
+
+		return str.toString();
+	}
+
+	private void render(StringBuffer str, boolean checkValues, boolean render,
+			int len, int value, String format, String desc, String prefix)
+			throws UOMoException {
+		if (render) {
+			if (value != -1) {
+				if (prefix != null)
+					str.append(prefix);
+				str.append(StringUtils.leftPad(Integer.toString(value), len,
+						Messages.Iso8601Date_ZERO));
+			} else if (checkValues)
+				throw new UOMoException(
+						Messages.Iso8601Date_NO_SUCH_VALUE_PROVIDED
+								+ format
+								+ "' specifies " + desc + " but no such value has been provided"); //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+
+	/**
+	 * Parse the value. no rules other than the base format rules
+	 * 
+	 * @param value
+	 *            - the value to parse
+	 */
+	public void parse(String value) {
+		parse(value, ISO_DATE_VALIDATION_FULL, OPTIONAL);
+	}
+
+	/**
+	 * Parse the value. check that it conforms to the specified format and
+	 * timezone rules
+	 * 
+	 * @param value
+	 *            - the value to parse
+	 * @param format
+	 *            - the format rules to adhere to
+	 * @param timezone
+	 *            - rules for timezone (REQUIRED, OPTIONAL, PROHIBITED, IGNORE)
+	 * @return - String description of parsing error, or null if no error
+	 *         encountered
+	 */
+	public String parse(String value, String format, int timezone) {
+		reset(timezone != IGNORE);
+		String[] parts = { value };
+		tzNegative = null;
+
+		if (value.indexOf('+') > 0) {
+			parts = StringUtils.split(value, "+", 2); //$NON-NLS-1$
+			tzNegative = new Boolean(false);
+		} else if (value.indexOf('-') > 0) {
+			parts = StringUtils.split(value, "-", 2); //$NON-NLS-1$
+			tzNegative = new Boolean(true);
+		}
+
+		String error = checkSections(parts[0], value, format);
+		if (error != null)
+			return error;
+
+		if (parts.length > 1 && timezone != IGNORE)
+			error = checkSections(parts[1], value, Messages.Iso8601Date_58);
+		if (error != null)
+			return error;
+
+		if (timezone == REQUIRED) {
+			if (parts.length < 2)
+				return Messages.Iso8601Date_59;
+		} else if (timezone == PROHIBITED && parts.length > 1)
+			return Messages.Iso8601Date_60;
+		return null;
+
+	}
+
+	/**
+	 * Parse the value to a Date. check that it conforms to the specified format
+	 * and timezone rules
+	 * 
+	 * @param value
+	 *            - the value to parse
+	 * @param format
+	 *            - the format rules to adhere to
+	 * @param timezone
+	 *            - rules for timezone (REQUIRED, OPTIONAL, PROHIBITED, IGNORE)
+	 * @return - Date (or throw exception if conversion not successful
+	 */
+	public static Date parseToDate(String value, String format, int timezone)
+			throws UOMoException {
+		Iso8601Date d = new Iso8601Date();
+		String err = d.parse(value, format, timezone);
+		if (err != null)
+			throw new UOMoException(Messages.Iso8601Date_61 + value
+					+ Messages.Iso8601Date_62 + err);
+		return d.getAsDate(timezone);
+	}
+
+	public static String renderFromDate(Date date, String format, int timezone)
+			throws UOMoException {
+		Iso8601Date d = new Iso8601Date();
+		d.setAsDate(date, timezone == REQUIRED ? SETLOCAL : CLEAR);
+		return d.render(format, true, timezone);
+	}
+
+	// private parsing routines
+
+	private boolean inFraction;
+
+	private String checkSections(String content, String whole, String mask) {
+		String workingMask = StringUtils.strip(mask, Messages.Iso8601Date_63);
+		String[] parts = { "", workingMask }; //$NON-NLS-1$
+		boolean first = true;
+		inFraction = false;
+
+		do {
+			parts = StringUtils.splitPreserveAllTokens(parts[1],
+					Messages.Iso8601Date_65, 2);
+			String token = parts[0];
+			if (token != null) { // support use of [ at first point to make
+									// everything optional
+				String section = content == null
+						|| content.length() < token.length() ? null : content
+						.substring(0, token.length()); // sSection =
+														// copy(sContent, 1,
+														// length(sToken));
+				if (section == null) { // if sSection = '' then
+					if (!first) {
+						if (content != null
+								&& content.length() < token.length())
+							return Messages.Iso8601Date_66 + content
+									+ Messages.Iso8601Date_67 + token;
+						else
+							return Messages.Iso8601Date_68 + token
+									+ Messages.Iso8601Date_69 + mask
+									+ Messages.Iso8601Date_70 + whole;
+					}
+				} else if (section.length() < token.length()) {
+					return Messages.Iso8601Date_71 + token
+							+ Messages.Iso8601Date_72 + mask
+							+ Messages.Iso8601Date_73 + whole
+							+ Messages.Iso8601Date_74 + section;
+				} else {
+					String error = checkSection(token, section);
+					if (error != null)
+						return error;
+					else if (section.length() >= content.length())
+						content = null;
+					else
+						content = content.substring(section.length());
+				}
+			}
+			first = false;
+		} while (parts.length > 1 && content != null); // until not result or
+														// (sFormat = '') or
+														// (sContent = '');
+		if (content != null) {
+			return Messages.Iso8601Date_75 + content + Messages.Iso8601Date_76
+					+ whole + Messages.Iso8601Date_77 + mask;
+		} else
+			return null;
+	}
+
+	private boolean starts(String source, String test) {
+		return source == null || source.length() < test.length() ? false
+				: source.substring(0, test.length()).equals(test);
+	}
+
+	private String checkSection(String token, String content) {
+		String error = null;
+
+		if (starts(token, Messages.Iso8601Date_YYYY)) {
+			error = checkYear(content.substring(0, 4));
+			if (error != null)
+				return error;
+			token = token.substring(4, token.length());
+			content = content.substring(4, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_MM)) {
+			error = checkMonth(content.substring(0, 2));
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_DD)) {
+			error = checkDay(content.substring(0, 2));
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_HH)) {
+			error = checkHour(content.substring(0, 2), false);
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_TT)) {
+			error = checkHour(content.substring(0, 2), true);
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_NN)) {
+			error = checkMinute(content.substring(0, 2), false);
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_tt)) {
+			error = checkMinute(content.substring(0, 2), true);
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, Messages.Iso8601Date_SS) && !inFraction) {
+			error = checkSecond(content.substring(0, 2));
+			if (error != null)
+				return error;
+			token = token.substring(2, token.length());
+			content = content.substring(2, content.length());
+		}
+		;
+
+		if (starts(token, ".") && !inFraction) { //$NON-NLS-1$
+			error = checkDot(content.substring(0, 1));
+			if (error != null)
+				return error;
+			token = token.substring(1, token.length());
+			content = content.substring(1, content.length());
+		}
+		;
+
+		while (starts(token, Messages.Iso8601Date_U) && inFraction) {
+			error = checkFraction(content.substring(0, 1));
+			if (error != null)
+				return error;
+			token = token.substring(1, token.length());
+			content = content.substring(1, content.length());
+		}
+		;
+
+		if (!(token == null || token.equals(""))) //$NON-NLS-1$
+			return Messages.Iso8601Date_DATE_FRAGMENT_NOT_KNOWN + token
+					+ " is not known"; //$NON-NLS-2$
+		return null;
+	}
+
+	private String checkYear(String value) {
+		if (value.length() != 4)
+			return "Year Value " + value + " is not 4 digits in length"; //$NON-NLS-1$ //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_YEAR_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else {
+			year = Integer.parseInt(value);
+			if (year <= 0)
+				return Messages.Iso8601Date_YEAR_VALUE_NEGATIVE_NOT_SUPPORTED
+						+ value + ": negative numbers are not supported"; //$NON-NLS-2$
+			else
+				return null;
+		}
+	}
+
+	private String checkMonth(String value) {
+		if (value.length() != 2)
+			return Messages.Iso8601Date_MONTH_VALUE_NOT_2_DIGITS + value
+					+ " is not 2 digits in length"; //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_MONTH_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else {
+			month = Integer.parseInt(value);
+			if (month <= 0 || month > 12)
+				return Messages.Iso8601Date_MONTH_VALUE_MUST_BE_1_12 + value
+						+ ": month must be 1 - 12"; //$NON-NLS-2$
+			else
+				return null;
+		}
+	}
+
+	private String checkDay(String value) {
+		if (value.length() != 2)
+			return Messages.Iso8601Date_DAY_VALUE_NOT_2_DIGITS + value
+					+ " is not 2 digits in length"; //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_DAY_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else {
+			day = Integer.parseInt(value);
+			if (day <= 0)
+				return Messages.Iso8601Date_DAY_VALUE_MUST_BE_POSITIVE + value
+						+ ": Day must be >= 1"; //$NON-NLS-2$
+			else if (month == 0)
+				return Messages.Iso8601Date_DAY_VALUE_MONTH_MUST_BE_KNOWN
+						+ value + ": Month must be known"; //$NON-NLS-2$
+			else if (year == 0)
+				return Messages.Iso8601Date_DAY_VALUE_YEAR_MUST_BE_KNOWN
+						+ value + ": Year must be known"; //$NON-NLS-2$
+			else if (day > daysForMonth(month, year))
+				return Messages.Iso8601Date_DAY_VALUE_ILLEGAL_FOR_MONTH
+						+ value
+						+ ": is illegal for the month " + Integer.toString(month) + "-" + Integer.toString(year); //$NON-NLS-2$ //$NON-NLS-3$
+			else
+				return null;
+		}
+	}
+
+	private int daysForMonth(int m, int y) {
+		int[] daysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+		if (m < 1 || m > 12)
+			return 30;
+		else if (m == 2 && new GregorianCalendar().isLeapYear(y))
+			return 29;
+		else
+			return daysInMonth[m - 1];
+	}
+
+	private String checkHour(String value, boolean inTimezone) {
+		if (value.length() != 2)
+			return Messages.Iso8601Date_HOUR_VALUE_NOT_2_DIGITS + value
+					+ " is not 2 digits in length"; //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_HOUR_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else if (inTimezone) {
+			tzHour = Integer.parseInt(value);
+			if (tzHour < 0)
+				return Messages.Iso8601Date_TZ_HOUR_VALUE_MUST_BE_0_OR_POSITIVE
+						+ value + ": Hour must be >= 0"; //$NON-NLS-2$
+			else if (tzHour > 12)
+				return Messages.Iso8601Date_TZ_HOUR_VALUE_MUST_BE_12_OR_LESS
+						+ value + ": Hour must be <= 12"; //$NON-NLS-2$
+		} else {
+			hour = Integer.parseInt(value);
+			if (hour < 0)
+				return Messages.Iso8601Date_HOUR_VALUE_MUST_BE_0_OR_POSITIVE
+						+ value + ": Hour must be >= 0"; //$NON-NLS-2$
+			else if (inTimezone && hour > 12)
+				return Messages.Iso8601Date_HOUR_VALUE_MUST_BE_12_OR_LESS
+						+ value + ": Hour must be <= 12"; //$NON-NLS-2$
+			else if (hour > 23)
+				return Messages.Iso8601Date_TZ_HOUR_VALUE_MUST_BE_23_OR_LESS
+						+ value + ": Hour must be <= 23"; //$NON-NLS-2$
+		}
+		return null;
+	}
+
+	private String checkMinute(String value, boolean inTimezone) {
+		if (value.length() != 2)
+			return Messages.Iso8601Date_MINUTE_VALUE_NOT_2_DIGITS_LONG + value
+					+ " is not 2 digits in length"; //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_MINUTE_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else if (inTimezone) {
+			tzMinute = Integer.parseInt(value);
+			if (tzMinute != 0 && tzMinute != 30)
+				return Messages.Iso8601Date_TZ_MINUTE_VALUE_MUST_BE_0_OR_30
+						+ value + ": Minute must be 0 or 30"; //$NON-NLS-2$
+		} else {
+			minute = Integer.parseInt(value);
+			if (minute < 0 || minute > 59)
+				return Messages.Iso8601Date_MINUTE_VALUE_MUST_BE_0_AND_59
+						+ value + ": Minute must be 0 and 59"; //$NON-NLS-2$
+		}
+		return null;
+	}
+
+	private String checkSecond(String value) {
+		if (value.length() != 2)
+			return Messages.Iso8601Date_SECOND_VALUE_NOT_2_DIGITS_LONG + value
+					+ " is not 2 digits in length"; //$NON-NLS-2$
+		else if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_SECOND_VALUE_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else {
+			second = Integer.parseInt(value);
+			if (second < 0 || second > 59)
+				return NLS.bind(
+						Messages.Iso8601Date_SECOND_VALUE_MUST_BE_0_AND_59,
+						value);
+			else
+				return null;
+		}
+	}
+
+	private String checkDot(String value) {
+		if (value.equals(".")) { //$NON-NLS-1$
+			inFraction = true;
+			return null;
+		} else
+			return Messages.Iso8601Date_EXPECTED_DOT;
+	}
+
+	private String checkFraction(String value) {
+		// TODO - read milliseconds
+		if (!StringUtils.isNumeric(value))
+			return Messages.Iso8601Date_FRACT_VAL_NOT_NUMERICAL + value
+					+ " is not numerical"; //$NON-NLS-2$
+		else
+			return null;
+	}
+
+	private String prepTimezone() {
+		return (tzNegative.booleanValue() ? Messages.Iso8601Date_MINUS
+				: Messages.Iso8601Date_PLUS)
+				+ StringUtils.leftPad(Integer.toString(tzHour), 2, '0')
+				+ StringUtils.leftPad(Integer.toString(tzMinute), 2, '0');
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/ErrorMessages.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/ErrorMessages.java
new file mode 100644
index 0000000..d3d2cb1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/ErrorMessages.java
@@ -0,0 +1,29 @@
+package org.eclipse.uomo.util.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ErrorMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.uomo.util.errors"; //$NON-NLS-1$
+	private static ResourceBundle RESOURCE_BUNDLE;
+
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, ErrorMessages.class);
+		RESOURCE_BUNDLE = ResourceBundle
+				.getBundle(BUNDLE_NAME);
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+	
+	private ErrorMessages() {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/Messages.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/Messages.java
new file mode 100644
index 0000000..9ba02fc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/Messages.java
@@ -0,0 +1,262 @@
+package org.eclipse.uomo.util.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.uomo.util.messages"; //$NON-NLS-1$
+	public static String Iso8601Date_58;
+	public static String Iso8601Date_59;
+	public static String Iso8601Date_60;
+	public static String Iso8601Date_61;
+	public static String Iso8601Date_62;
+	public static String Iso8601Date_63;
+	public static String Iso8601Date_65;
+	public static String Iso8601Date_66;
+	public static String Iso8601Date_67;
+	public static String Iso8601Date_68;
+	public static String Iso8601Date_69;
+	public static String Iso8601Date_70;
+	public static String Iso8601Date_71;
+	public static String Iso8601Date_72;
+	public static String Iso8601Date_73;
+	public static String Iso8601Date_74;
+	public static String Iso8601Date_75;
+	public static String Iso8601Date_76;
+	public static String Iso8601Date_77;
+	public static String Iso8601Date_DATE_FRAGMENT_NOT_KNOWN;
+	public static String Iso8601Date_day;
+	public static String Iso8601Date_DAY_VALUE_ILLEGAL_FOR_MONTH;
+	public static String Iso8601Date_DAY_VALUE_MONTH_MUST_BE_KNOWN;
+	public static String Iso8601Date_DAY_VALUE_MUST_BE_POSITIVE;
+	public static String Iso8601Date_DAY_VALUE_NOT_2_DIGITS;
+	public static String Iso8601Date_DAY_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_DAY_VALUE_YEAR_MUST_BE_KNOWN;
+	public static String Iso8601Date_DAYS;
+	public static String Iso8601Date_dd;
+	public static String Iso8601Date_DD;
+	public static String Iso8601Date_DEF_OUTPUT_FORMAT;
+	public static String Iso8601Date_DOT;
+	public static String Iso8601Date_EXPECTED_DOT;
+	public static String Iso8601Date_FRACT_VAL_NOT_NUMERICAL;
+	public static String Iso8601Date_GMT;
+	public static String Iso8601Date_HH;
+	public static String Iso8601Date_hh;
+	public static String Iso8601Date_hour;
+	public static String Iso8601Date_HOUR_VALUE_MUST_BE_0_OR_POSITIVE;
+	public static String Iso8601Date_HOUR_VALUE_MUST_BE_12_OR_LESS;
+	public static String Iso8601Date_HOUR_VALUE_NOT_2_DIGITS;
+	public static String Iso8601Date_HOUR_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_HOURS;
+	public static String Iso8601Date_ISO_DATE_VALIDATION_DATE;
+	public static String Iso8601Date_ISO_DATE_VALIDATION_FULL;
+	public static String Iso8601Date_MILIS;
+	public static String Iso8601Date_milisecond;
+	public static String Iso8601Date_MINUS;
+	public static String Iso8601Date_minute;
+	public static String Iso8601Date_MINUTE_VALUE_MUST_BE_0_AND_59;
+	public static String Iso8601Date_MINUTE_VALUE_NOT_2_DIGITS_LONG;
+	public static String Iso8601Date_MINUTE_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_MINUTES;
+	public static String Iso8601Date_mm;
+	public static String Iso8601Date_MM;
+	public static String Iso8601Date_month;
+	public static String Iso8601Date_MONTH_VALUE_MUST_BE_1_12;
+	public static String Iso8601Date_MONTH_VALUE_NOT_2_DIGITS;
+	public static String Iso8601Date_MONTH_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_MONTHS;
+	public static String Iso8601Date_nn;
+	public static String Iso8601Date_NN;
+	public static String Iso8601Date_NO_SUCH_VALUE_PROVIDED;
+	public static String Iso8601Date_NO_VALUES_SET;
+	public static String Iso8601Date_PLUS;
+	public static String Iso8601Date_s;
+	public static String Iso8601Date_second;
+	public static String Iso8601Date_SECOND_VALUE_MUST_BE_0_AND_59;
+	public static String Iso8601Date_SECOND_VALUE_NOT_2_DIGITS_LONG;
+	public static String Iso8601Date_SECOND_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_SECONDS;
+	public static String Iso8601Date_ss;
+	public static String Iso8601Date_SS;
+	public static String Iso8601Date_sss;
+	public static String Iso8601Date_THE_DAY;
+	public static String Iso8601Date_TT;
+	public static String Iso8601Date_tt;
+	public static String Iso8601Date_tz_hour;
+	public static String Iso8601Date_TZ_HOUR_VALUE_MUST_BE_0_OR_POSITIVE;
+	public static String Iso8601Date_TZ_HOUR_VALUE_MUST_BE_12_OR_LESS;
+	public static String Iso8601Date_TZ_HOUR_VALUE_MUST_BE_23_OR_LESS;
+	public static String Iso8601Date_TZ_HOURS;
+	public static String Iso8601Date_TZ_MINUTE_VALUE_MUST_BE_0_OR_30;
+	public static String Iso8601Date_tz_minutes;
+	public static String Iso8601Date_TZ_MINUTES;
+	public static String Iso8601Date_TZ_NOT_DEFINED;
+	public static String Iso8601Date_TZ_PROHIBITED_BUT_DEFINED;
+	public static String Iso8601Date_TZ_REQUIRED_BUT_NOT_DEFINED;
+	public static String Iso8601Date_U;
+	public static String Iso8601Date_VALUE_INVALID;
+	public static String Iso8601Date_VALUE_MISSING;
+	public static String Iso8601Date_year;
+	public static String Iso8601Date_YEAR_VALUE_NEGATIVE_NOT_SUPPORTED;
+	public static String Iso8601Date_YEAR_VALUE_NOT_NUMERICAL;
+	public static String Iso8601Date_YEARS;
+	public static String Iso8601Date_yyyy;
+	public static String Iso8601Date_YYYY;
+	public static String Iso8601Date_ZERO;
+	public static String NumberValidator_a_number;
+	public static String NumberValidator_an_Exponent;
+	public static String NumberValidator_an_Integer;
+	public static String NumberValidator_decimal_portion;
+	public static String NumberValidator_DOT;
+	public static String NumberValidator_E;
+	public static String NumberValidator_Exponent_Format_not_allowed_in_Context;
+	public static String NumberValidator_Exponent_Format_required_in_Context;
+	public static String NumberValidator_INF;
+	public static String NumberValidator_minusINF;
+	public static String NumberValidator_NaN;
+	public static String NumberValidator_Number_empty;
+	public static String NumberValidator_Only_Digits_after_Decimal_allowed_but_found;
+	public static String NumberValidator_plusINF;
+	public static String NumberValidator_Unexpected_Content_after_Parsing_Decimal;
+	public static String NumberValidator_Unexpected_Content_after_Parsing_Exponent;
+	public static String NumberValidator_Unexpected_Content_after_Parsing_Int;
+	public static String NumberValidator_Unexpected_Content_at_Char_expecting_E;
+	public static String NumberValidator_Unexpected_Content_expecting_Start_of;
+	public static String NumberValidator_Unexpected_Content_following_in_Decimal;
+	public static String NumberValidator_Unexpected_Content_NaN;
+	public static String NumberValidator_Unexpected_End_of_Source_after_Sign_looking_for;
+	public static String NumberValidator_Unexpected_End_of_Source;
+	public static String NumberValidator_Unexpected_End_of_Source_looking_for;
+	public static String NumberValidator_Value_Infinity;
+	public static String NumberValidator_Value_negative_Infinity;
+	public static String NumberValidator_Value_not_a_number;
+	public static String RomanNumberSpeller_0;
+	public static String RomanNumberSpeller_10;
+	public static String RomanNumberSpeller_11;
+	public static String RomanNumberSpeller_12;
+	public static String RomanNumberSpeller_13;
+	public static String RomanNumberSpeller_14;
+	public static String RomanNumberSpeller_2;
+	public static String RomanNumberSpeller_3;
+	public static String RomanNumberSpeller_4;
+	public static String RomanNumberSpeller_5;
+	public static String RomanNumberSpeller_6;
+	public static String RomanNumberSpeller_7;
+	public static String RomanNumberSpeller_8;
+	public static String RomanNumberSpeller_9;
+	public static String Speller_0;
+	public static String Speller_100;
+	public static String Speller_102;
+	public static String Speller_104;
+	public static String Speller_106;
+	public static String Speller_108;
+	public static String Speller_110;
+	public static String Speller_112;
+	public static String Speller_114;
+	public static String Speller_116;
+	public static String Speller_118;
+	public static String Speller_120;
+	public static String Speller_122;
+	public static String Speller_124;
+	public static String Speller_126;
+	public static String Speller_128;
+	public static String Speller_130;
+	public static String Speller_132;
+	public static String Speller_134;
+	public static String Speller_136;
+	public static String Speller_138;
+	public static String Speller_140;
+	public static String Speller_142;
+	public static String Speller_144;
+	public static String Speller_146;
+	public static String Speller_148;
+	public static String Speller_15;
+	public static String Speller_150;
+	public static String Speller_152;
+	public static String Speller_154;
+	public static String Speller_156;
+	public static String Speller_158;
+	public static String Speller_16;
+	public static String Speller_160;
+	public static String Speller_165;
+	public static String Speller_166;
+	public static String Speller_17;
+	public static String Speller_18;
+	public static String Speller_19;
+	public static String Speller_20;
+	public static String Speller_207;
+	public static String Speller_208;
+	public static String Speller_21;
+	public static String Speller_22;
+	public static String Speller_23;
+	public static String Speller_24;
+	public static String Speller_25;
+	public static String Speller_26;
+	public static String Speller_27;
+	public static String Speller_28;
+	public static String Speller_29;
+	public static String Speller_3;
+	public static String Speller_30;
+	public static String Speller_31;
+	public static String Speller_32;
+	public static String Speller_33;
+	public static String Speller_34;
+	public static String Speller_35;
+	public static String Speller_36;
+	public static String Speller_37;
+	public static String Speller_38;
+	public static String Speller_39;
+	public static String Speller_4;
+	public static String Speller_40;
+	public static String Speller_41;
+	public static String Speller_42;
+	public static String Speller_43;
+	public static String Speller_44;
+	public static String Speller_45;
+	public static String Speller_46;
+	public static String Speller_47;
+	public static String Speller_48;
+	public static String Speller_49;
+	public static String Speller_5;
+	public static String Speller_51;
+	public static String Speller_52;
+	public static String Speller_55;
+	public static String Speller_58;
+	public static String Speller_59;
+	public static String Speller_60;
+	public static String Speller_61;
+	public static String Speller_62;
+	public static String Speller_63;
+	public static String Speller_64;
+	public static String Speller_65;
+	public static String Speller_66;
+	public static String Speller_68;
+	public static String Speller_7;
+	public static String Speller_70;
+	public static String Speller_72;
+	public static String Speller_78;
+	public static String Speller_8;
+	public static String Speller_80;
+	public static String Speller_81;
+	public static String Speller_82;
+	public static String Speller_83;
+	public static String Speller_84;
+	public static String Speller_86;
+	public static String Speller_88;
+	public static String Speller_9;
+	public static String Speller_90;
+	public static String Speller_92;
+	public static String Speller_94;
+	public static String Speller_96;
+	public static String Speller_97;
+	public static String Speller_98;
+	public static String Speller_Crore;
+	public static String Speller_Lakh;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+	
+	private Messages() {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/UtilitiesPlugin.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/UtilitiesPlugin.java
new file mode 100644
index 0000000..21bb725
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/internal/UtilitiesPlugin.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.util.internal;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class UtilitiesPlugin extends Plugin {
+
+	//The shared instance.
+	private static UtilitiesPlugin plugin;
+	
+	/**
+	 * The constructor.
+	 */
+	public UtilitiesPlugin() {
+		plugin = this;
+	}
+
+	/**
+	 * This method is called upon plug-in activation
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+	}
+
+	/**
+	 * This method is called when the plug-in is stopped
+	 */
+	public void stop(BundleContext context) throws Exception {
+		super.stop(context);
+		plugin = null;
+	}
+
+	/**
+	 * Returns the shared instance.
+	 */
+	public static UtilitiesPlugin getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/DecimalFormatOptions.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/DecimalFormatOptions.java
new file mode 100644
index 0000000..37b824f
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/DecimalFormatOptions.java
@@ -0,0 +1,43 @@
+package org.eclipse.uomo.util.numbers;
+
+abstract class DecimalFormatOptions {
+
+	protected static final int ANY_DIGITS = -1;
+	/**
+	 * If totalDigits is specified, the number of digits must be less than or equal to totalDigits.
+	 */
+	protected int totalDigits;
+	/**
+	 * If fractionDigits is specified, the number of digits following the decimal point must be less than or equal to the fractionDigits 
+	 */
+	protected int fractionDigits;
+
+	/**
+	 * @return the totalDigits
+	 */
+	public int getTotalDigits() {
+		return totalDigits;
+	}
+
+	/**
+	 * @param totalDigits the totalDigits to set
+	 */
+	public void setTotalDigits(int totalDigits) {
+		this.totalDigits = totalDigits;
+	}
+
+	/**
+	 * @return the fractionDigits
+	 */
+	public int getFractionDigits() {
+		return fractionDigits;
+	}
+
+	/**
+	 * @param fractionDigits the fractionDigits to set
+	 */
+	public void setFractionDigits(int fractionDigits) {
+		this.fractionDigits = fractionDigits;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpellCode.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpellCode.java
new file mode 100644
index 0000000..d6dd967
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpellCode.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API
+ */
+package org.eclipse.uomo.util.numbers;
+
+import org.eclipse.uomo.core.ICode;
+import org.eclipse.uomo.core.IName;
+import org.eclipse.uomo.core.INumericValue;
+
+/**
+ * In this project, we have used a unique way of encoding spelled number to a
+ * string. Each known word (or punctuation) in a spelled number string is
+ * converted to a case-sensitive single-character code. For example, the spelled
+ * number:
+ * 
+ * Two Thousand, Three Hundred and Nine (2,309)
+ * 
+ * is encoded as:
+ * 
+ * 2T,3I&9
+ * 
+ * In this encoding,
+ * 
+ * 2 represents the word: "two", T represents the word: :thousand", Comma (,)
+ * represents itself, 3 represents the word: "three", I represents the word:
+ * "hundred", ampersand (&) represents the word: "and", and finally, 9
+ * represents the word nine.
+ * 
+ * The great advantage of this encoding is that it would be fairly easy to
+ * validate a text as being a correct spelled number using regular expression.
+ * 
+ * SpellCode class is a way to hold encoding and recognition information for a
+ * single known word in spelling contexts. These are words like thousand,
+ * fourteen etc which all have a name (e.g., fourteen), a dedicated
+ * case-sensitive single-character code (U) and an associative value (14).
+ * 
+ * @author Werner Keil
+ * 
+ * @see {@link SpellContext#myCodes} the definition of myCodes array (a static
+ *      member of SpellContext class) for the codes uniquely proposed and used
+ *      in this project.
+ * @see {@link SpellContext#encode(String)}
+ * 
+ */
+public interface ISpellCode extends IName, ICode, INumericValue {
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpeller.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpeller.java
new file mode 100644
index 0000000..99cc6c4
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/ISpeller.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2009, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers;
+
+import org.eclipse.uomo.util.Parser;
+
+/**
+ * A tool for number spelling, text parsing and encoding.
+ * 
+ * @author Werner Keil
+ * @version 1.0
+ */
+public interface ISpeller extends Parser<String, Number> {
+	/**
+	 * Spells a number; converts a number to its equivalent read-out text
+	 * string.
+	 * 
+	 * @param number
+	 *            The number to be spelled.
+	 * 
+	 * @return The word by word read-out of the number - correctly spelled and
+	 *         punctuated.
+	 * 
+	 * @throws SpellException
+	 *             If this method throws an exception. Please report it.
+	 */
+	public String spell(long number) throws SpellException;
+
+	/**
+	 * For public use: parses a human-readable spelling text of a number, and
+	 * converts it to the corresponding numeric value.
+	 * 
+	 * @param text
+	 *            the human-readable spelling text of a number.
+	 * @return the numeric value corresponding to the human-readable number
+	 *         text.
+	 * @throws SpellException
+	 *             if the text contains intolerable, misplaced or unknown word.
+	 * 
+	 * @see {@link #parseInternal(String)} which does a similar operation with
+	 *      text not possibly started with word ''minus''. Actually, it does the
+	 *      main operation.
+	 */
+	@Override
+	public Number parse(String text) throws SpellException;
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberFormatUtilities.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberFormatUtilities.java
new file mode 100644
index 0000000..1faa147
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberFormatUtilities.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Grahame Grieve - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers;
+
+import java.math.BigDecimal;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * This provides services directly targeted at supporting messages like HL7. The
+ * formats are not localized
+ * 
+ * @author Grahame Grieve
+ * @author Werner Keil
+ * @version 1.1
+ * 
+ */
+public abstract class NumberFormatUtilities {
+
+	/**
+	 * validate that a string is a valid real number. validates the entire
+	 * source string.
+	 * 
+	 * this accepts either xs:double or xs:decimal
+	 * 
+	 * @param source
+	 *            - the source to check
+	 * @param options
+	 *            - may be null
+	 * @return null if valid, otherwise an error
+	 */
+	public static String validateReal(String source, RealFormatOptions options) {
+		try {
+			new NumberValidator(source, options).validateReal();
+			return null;
+		} catch (NumberFormatException e) {
+			return e.getMessage();
+		}
+	}
+
+	/**
+	 * convert a real number to a BigDecimal
+	 * 
+	 * @param source
+	 * @return
+	 * @throws UOMoNumberFormatException
+	 */
+	public static BigDecimal parseReal(String source, RealFormatOptions options)
+			throws UOMoNumberFormatException {
+		return new NumberValidator(source, null).parseReal();
+	}
+
+	@Deprecated
+	public static String formatReal(BigDecimal num) {
+		return NumberFormat.getInstance(Locale.US).format(num);
+	}
+
+	@Deprecated
+	public static String formatReal(Double num) {
+		return NumberFormat.getInstance(Locale.US).format(num);
+	}
+
+	public static String validateInteger(String source) {
+		try {
+			new NumberValidator(source, null).validateInteger();
+			return null;
+		} catch (NumberFormatException e) {
+			return e.getMessage();
+		}
+	}
+
+	public static long parseInteger(String source)
+			throws UOMoNumberFormatException {
+		return new NumberValidator(source, null).parseInteger();
+	}
+
+	public static String formatInteger(Long num) {
+		return NumberFormat.getInstance(Locale.US).format(num.longValue());
+	}
+
+	public static String formatInteger(long num) {
+		return NumberFormat.getInstance(Locale.US).format(num);
+	}
+
+	public static String validateDecimal(String source,
+			DecimalFormatOptions options) {
+		try {
+			new NumberValidator(source, options).validateDecimal();
+			return null;
+		} catch (NumberFormatException e) {
+			return e.getMessage();
+		}
+	}
+
+	public static BigDecimal parseDecimal(String source,
+			DecimalFormatOptions options) throws UOMoNumberFormatException {
+		return new NumberValidator(source, null).parseDecimal();
+	}
+
+	public static String formatDecimal(BigDecimal num) {
+		return NumberFormat.getInstance(Locale.US).format(num);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberValidator.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberValidator.java
new file mode 100644
index 0000000..7ea9cb5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/NumberValidator.java
@@ -0,0 +1,289 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Grahame Grieve - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers;
+
+import static org.eclipse.uomo.util.numbers.UOMoNumberFormatException.Kind.*;
+
+import java.math.BigDecimal;
+
+import org.eclipse.uomo.util.internal.Messages;
+
+/**
+ * Double: a mantissa followed, optionally, by the character "E" or "e",
+ * followed by an exponent. The exponent must be an integer. The mantissa must
+ * be a decimal number. The representations for exponent and mantissa must
+ * follow the lexical rules for integer and decimal. If the "E" or "e" and the
+ * following exponent are omitted, an exponent value of 0 is assumed.
+ * 
+ * The special values positive and negative zero, positive and negative infinity
+ * and not-a-number have lexical representations 0, -0, INF, -INF and NaN,
+ * respectively.
+ * 
+ * Decimal: decimal has a lexical representation consisting of a finite-length
+ * sequence of decimal digits (#x30-#x39) separated by a period as a decimal
+ * indicator. An optional leading sign is allowed. If the sign is omitted, "+"
+ * is assumed. Leading and trailing zeroes are optional. If the fractional part
+ * is zero, the period and following zero(es) can be omitted.
+ * 
+ * @author Grahame Grieve
+ */
+
+class NumberValidator {
+
+	private String source;
+	private int cursor;
+	private DecimalFormatOptions options;
+
+	private String whole;
+	private String decimals;
+	private String exponent;
+
+	/**
+	 * @param source
+	 * @param cursor
+	 * @param options
+	 */
+	protected NumberValidator(String source, DecimalFormatOptions options) {
+		super();
+		this.source = source;
+		this.cursor = 0;
+		this.options = options;
+	}
+
+	private boolean optionsBanExponent() {
+		return options != null && options instanceof RealFormatOptions
+				&& ((RealFormatOptions) options).getExponent() != null
+				&& !((RealFormatOptions) options).getExponent().booleanValue();
+	}
+
+	private boolean optionsRequireExponent() {
+		return options != null && options instanceof RealFormatOptions
+				&& ((RealFormatOptions) options).getExponent() != null
+				&& ((RealFormatOptions) options).getExponent().booleanValue();
+	}
+
+	private boolean optionsAllowSpecial() {
+		return options != null && options instanceof RealFormatOptions
+				&& ((RealFormatOptions) options).isAllowSpecial();
+	}
+
+	private boolean more() {
+		return cursor < source.length();
+	}
+
+	private char peek() {
+		if (!more())
+			return ' ';
+		else
+			return source.charAt(cursor);
+	}
+
+	private char next() {
+		char ch = peek();
+		cursor++;
+		return ch;
+	}
+
+	private String pos() {
+		return Integer.toString(cursor);
+	}
+
+	private void start() throws UOMoNumberFormatException {
+		if (source == null || source.equals("")) //$NON-NLS-1$
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Number_empty);
+
+		whole = null;
+		decimals = null;
+		exponent = null;
+	}
+
+	public long parseInteger() throws UOMoNumberFormatException {
+		validateInteger();
+		try {
+			return Long.parseLong(whole);
+		} catch (Exception e) {
+			// can get to here if the number is too big
+			throw new UOMoNumberFormatException(SIZE, e.getMessage());
+		}
+	}
+
+	public BigDecimal parseDecimal() throws UOMoNumberFormatException {
+		validateDecimal();
+		try {
+			return new BigDecimal(whole
+					+ (decimals == null ? "" : Messages.NumberValidator_DOT + decimals)); //$NON-NLS-1$
+		} catch (NumberFormatException e) {
+			// can get to here if the number is too big (for example,
+			// 1.0e10000000000000000000000000000000000000000000000000000000)
+			throw new UOMoNumberFormatException(SIZE, e.getMessage());
+		}
+	}
+
+	public BigDecimal parseReal() throws UOMoNumberFormatException {
+		validateReal();
+		if (whole.equals(NaN))
+			throw new UOMoNumberFormatException(NaN, Messages.NumberValidator_Value_not_a_number);
+		else if (whole.equals(Messages.NumberValidator_INF) || whole.equals(Messages.NumberValidator_plusINF))
+			throw new UOMoNumberFormatException(PINF, Messages.NumberValidator_Value_Infinity);
+		else if (whole.equals(Messages.NumberValidator_minusINF))
+			throw new UOMoNumberFormatException(NINF,
+					Messages.NumberValidator_Value_negative_Infinity);
+		else
+			try {
+				return new BigDecimal(whole
+						+ (decimals == null ? "" : "." + decimals) //$NON-NLS-1$
+						+ (exponent == null ? "" : Messages.NumberValidator_E + exponent)); //$NON-NLS-1$
+			} catch (NumberFormatException e) {
+				throw new UOMoNumberFormatException(SIZE,
+						e.getLocalizedMessage());
+			}
+	}
+
+	public void validateInteger() throws UOMoNumberFormatException {
+		start();
+		whole = processInteger(true, false, Messages.NumberValidator_an_Integer);
+		if (more())
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Unexpected_Content_after_Parsing_Int + peek() + "' at character " + pos() //$NON-NLS-2$
+							+ " after parsing integer"); //$NON-NLS-1$
+	}
+
+	public void validateReal() throws UOMoNumberFormatException {
+		start();
+
+		processDecimal();
+		if (more()) {
+			if (peek() != 'e' && peek() != 'E')
+				throw new UOMoNumberFormatException(TEXT_FORMAT,
+						Messages.NumberValidator_Unexpected_Content_at_Char_expecting_E + peek() + "' at character " //$NON-NLS-2$
+								+ pos() + " expecting e or E"); //$NON-NLS-1$
+			if (optionsBanExponent())
+				throw new UOMoNumberFormatException(RULE,
+						Messages.NumberValidator_Exponent_Format_not_allowed_in_Context);
+			next();
+			exponent = processInteger(true, false, Messages.NumberValidator_an_Exponent);
+			if (more()) {
+				throw new UOMoNumberFormatException(TEXT_FORMAT,
+						Messages.NumberValidator_Unexpected_Content_after_Parsing_Exponent + peek() + "' at character " //$NON-NLS-2$
+								+ pos() + " after parsing exponent"); //$NON-NLS-1$
+			}
+		} else if (optionsRequireExponent())
+			throw new UOMoNumberFormatException(
+					UOMoNumberFormatException.Kind.RULE,
+					Messages.NumberValidator_Exponent_Format_required_in_Context);
+
+		checkDigits();
+	}
+
+	public void validateDecimal() throws UOMoNumberFormatException {
+		start();
+
+		processDecimal();
+		if (more())
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Unexpected_Content_after_Parsing_Decimal + peek() + "' at character " + pos() //$NON-NLS-2$
+							+ " after parsing decimal"); //$NON-NLS-1$
+
+		checkDigits();
+	}
+
+	private void checkDigits() throws UOMoNumberFormatException {
+		if (options != null) {
+			if (options.getFractionDigits() != DecimalFormatOptions.ANY_DIGITS
+					&& decimals != null) {
+				if (decimals.length() > options.getFractionDigits())
+					throw new UOMoNumberFormatException(
+							UOMoNumberFormatException.Kind.RULE,
+							Messages.NumberValidator_Only_Digits_after_Decimal_allowed_but_found
+									+ Integer.toString(options
+											.getFractionDigits())
+									+ " digits after the decimal are allowed, but found " //$NON-NLS-1$
+									+ Integer.toString(decimals.length()));
+			}
+			if (options.getTotalDigits() != DecimalFormatOptions.ANY_DIGITS) {
+				int len = whole.length()
+						+ (decimals == null ? 0 : decimals.length());
+				if (len > options.getTotalDigits())
+					throw new UOMoNumberFormatException(
+							UOMoNumberFormatException.Kind.RULE,
+							"Only " //$NON-NLS-1$
+									+ Integer.toString(options.getTotalDigits())
+									+ " digits after the decimal are allowed, but found " //$NON-NLS-1$
+									+ Integer.toString(len));
+			}
+		}
+	}
+
+	private String processInteger(boolean allowSign, boolean allowComplex,
+			String context) throws UOMoNumberFormatException {
+		if (!more())
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Unexpected_End_of_Source_looking_for + context);
+		StringBuffer b = new StringBuffer();
+		if (allowSign && (peek() == '+' || peek() == '-')) {
+			if (peek() == '+')
+				next();
+			else
+				b.append(next());
+		}
+		if (!more())
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Unexpected_End_of_Source_after_Sign_looking_for
+							+ context);
+		if (allowComplex && peek() == 'N') {
+			processSequence(Messages.NumberValidator_NaN, context);
+			b.append("NaN"); //$NON-NLS-1$
+		} else if (allowComplex && peek() == 'I') {
+			processSequence("INF", context);
+			b.append("INF");
+		} else {
+			if (peek() < '0' || peek() > '9')
+				throw new UOMoNumberFormatException(TEXT_FORMAT,
+						Messages.NumberValidator_Unexpected_Content_expecting_Start_of + peek() + "' at character " //$NON-NLS-2$
+								+ pos() + " expecting the start of " + context); //$NON-NLS-1$
+			while (more() && peek() >= '0' && peek() <= '9')
+				b.append(next());
+		}
+		return b.toString();
+	}
+
+	private void processSequence(String mask, String context)
+			throws UOMoNumberFormatException {
+		for (int i = 0; i < mask.length(); i++) {
+			if (!more())
+				throw new UOMoNumberFormatException(TEXT_FORMAT,
+						Messages.NumberValidator_Unexpected_End_of_Source + mask
+								+ "' in " + context); //$NON-NLS-1$
+			char ch = next();
+			if (ch != mask.charAt(i))
+				throw new UOMoNumberFormatException(TEXT_FORMAT,
+						Messages.NumberValidator_Unexpected_Content_NaN + ch + "' at character " + pos() //$NON-NLS-2$
+								+ " attempting to read 'NaN' in " + context); //$NON-NLS-1$
+		}
+		if (more())
+			throw new UOMoNumberFormatException(TEXT_FORMAT,
+					Messages.NumberValidator_Unexpected_Content_following_in_Decimal + peek() + "' at character " + pos() //$NON-NLS-2$
+							+ " following '" + mask + "' in " + context); //$NON-NLS-1$ //$NON-NLS-2$
+
+	}
+
+	private void processDecimal() throws UOMoNumberFormatException {
+		whole = processInteger(true, options == null || optionsAllowSpecial(),
+				Messages.NumberValidator_a_number);
+		if (more() && peek() == '.') {
+			next();
+			decimals = processInteger(false, false, Messages.NumberValidator_decimal_portion);
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/RealFormatOptions.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/RealFormatOptions.java
new file mode 100644
index 0000000..cd31ece
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/RealFormatOptions.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Grahame Grieve - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers;
+
+final class RealFormatOptions extends DecimalFormatOptions {
+	
+	/**
+	 * null - exponent form is allowed
+	 * false - exponent form is not allowed
+	 * true - exponent form is required
+	 * 
+	 * FIXME change this to a more descriptive enum
+	 */
+	private Boolean exponent;
+	private boolean allowSpecial;
+	
+	/**
+	 * @param exponent
+	 * @param totalDigits
+	 * @param fractionDigits
+	 */
+	public RealFormatOptions(Boolean exponent, boolean allowSpecial, int totalDigits, int fractionDigits) {
+		super();
+		this.exponent = exponent;
+		this.totalDigits = totalDigits;
+		this.fractionDigits = fractionDigits;
+		this.allowSpecial = allowSpecial;
+	}
+
+	/**
+	 * @return the exponent
+	 */
+	public Boolean getExponent() {
+		return exponent;
+	}
+
+	/**
+	 * @param exponent the exponent to set
+	 */
+	public void setExponent(Boolean exponent) {
+		this.exponent = exponent;
+	}
+
+	/**
+	 * @return the allowSpecial
+	 */
+	public boolean isAllowSpecial() {
+		return allowSpecial;
+	}
+
+	/**
+	 * @param allowSpecial the allowSpecial to set
+	 */
+	public void setAllowSpecial(boolean allowSpecial) {
+		this.allowSpecial = allowSpecial;
+	}
+
+	public static RealFormatOptions allowComplex() {
+		return new RealFormatOptions(null, true, ANY_DIGITS, ANY_DIGITS);
+	}
+	
+	
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellException.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellException.java
new file mode 100644
index 0000000..f1b1386
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellException.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2009, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers;
+
+import org.eclipse.uomo.core.UOMoException;
+
+
+/**
+* @author Werner Keil
+* 
+*         A simple checked exception class.
+* 
+*/
+public class SpellException extends UOMoException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1358891223155703756L;
+
+	/**
+	 * @param message
+	 *            The message carried by this exception object
+	 */
+	public SpellException(String message) {
+		super(message);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellService.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellService.java
new file mode 100644
index 0000000..c5de471
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/SpellService.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API
+ */
+package org.eclipse.uomo.util.numbers;
+
+/**
+ * SpellService is main engine for number spelling, text parsing and encoding
+ * and validating.
+ * 
+ * @author Werner Keil
+ * @version 1.1
+ */
+public interface SpellService {
+
+	/**
+	 * Register a speller
+	 * 
+	 * @param speller
+	 *            the speller to be added.
+	 */
+	public void registerSpeller(ISpeller speller);
+
+	/**
+	 * Remove a speller
+	 * 
+	 * @param speller
+	 *            the speller to be removed.
+	 */
+	public void unregisterSpeller(ISpeller dictionary);
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/UOMoNumberFormatException.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/UOMoNumberFormatException.java
new file mode 100644
index 0000000..4af3a91
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/UOMoNumberFormatException.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Creative Arts & Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Werner Keil, Creative Arts & Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.util.numbers;
+
+import org.eclipse.uomo.util.internal.ErrorMessages;
+
+/**
+ * @author Werner Keil
+ * @version 1.2, $Date: 2010-08-22 23:13:45 +0200 (So, 22 Aug 2010) $
+ */
+public class UOMoNumberFormatException extends NumberFormatException {
+
+	private static final long serialVersionUID = 5056915330109108078L;
+
+	public static enum Kind {
+		TEXT_FORMAT, NaN, PINF, NINF, SIZE, RULE, INTERNAL
+		// shouldn't ever happen
+	}
+
+	private final Kind kind;
+
+	/**
+	 * @param arg0
+	 */
+	public UOMoNumberFormatException(Kind kind, String msg) {
+		super(msg);
+		this.kind = kind;
+	}
+
+	public String getMessageForKind() {
+		return getMessageForKind(kind);
+	}
+
+	public static String getMessageForKind(Kind kind) {
+		return ErrorMessages.getString("UOMoNumberFormatException." + kind.name()); //$NON-NLS-1$		}
+	}
+
+	/**
+	 * @return the kind
+	 */
+	public Kind getKind() {
+		return kind;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/IndianNumberSpeller.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/IndianNumberSpeller.java
new file mode 100644
index 0000000..a2984a6
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/IndianNumberSpeller.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+import org.eclipse.uomo.util.internal.Messages;
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.SpellException;
+
+/**
+ * @version 1.1, 2013-05-12
+ * @author Werner Keil
+ *
+ */
+public class IndianNumberSpeller implements ISpeller {
+	private static IndianNumberSpeller INSTANCE;
+	private String string;
+	private final String mySingleText[] = { "", Messages.Speller_22,
+			Messages.Speller_23, Messages.Speller_24, Messages.Speller_25,
+			Messages.Speller_26, Messages.Speller_27, Messages.Speller_28,
+			Messages.Speller_29, Messages.Speller_30 };
+	private final String myTeenText[] = { Messages.Speller_104, Messages.Speller_106,
+			Messages.Speller_108, Messages.Speller_110, Messages.Speller_112,
+			Messages.Speller_114, Messages.Speller_116, Messages.Speller_118,
+			Messages.Speller_120, Messages.Speller_122 };
+	private final String myCentText[] = { "Twenty", "Thirty", "Fourty", "Fifty",
+			"Sixty", "Seventy", "Eighty", "Ninty" };
+	private final String myCroreText[] = { Messages.Speller_140, "Thousand",
+			Messages.Speller_Lakh, Messages.Speller_Crore };
+
+	// singleton
+	private IndianNumberSpeller() {}
+	
+	/**
+	 * @return the default instance
+	 */
+	public static final IndianNumberSpeller of() {
+		if (INSTANCE == null) {
+			INSTANCE = new IndianNumberSpeller();
+		}
+		return INSTANCE;
+	}
+		
+	public String spell(final long number) throws SpellException {
+		if (number < Integer.MIN_VALUE || number < -Integer.MAX_VALUE
+				|| number > Integer.MAX_VALUE) {
+			throw new SpellException(number
+					+ " exceeds allowed value for this algorithm.");
+		}
+		int numToConvert = (int) number;
+		int in = 1;
+		int num = -1;
+		string = "";
+		while (numToConvert != 0) {
+			switch (in) {
+			case 1:
+				num = numToConvert % 100;
+				passString(num);
+				if (numToConvert > 100 && numToConvert % 100 != 0) {
+					displayOutput(Messages.Speller_7);
+				}
+				numToConvert /= 100;
+				break;
+			case 2:
+				num = numToConvert % 10;
+				if (num != 0) {
+					displayOutput(" ");
+					displayOutput(myCroreText[0]);
+					displayOutput(" ");
+					passString(num);
+				}
+				numToConvert /= 10;
+				break;
+
+			case 3:
+				num = numToConvert % 100;
+				if (num != 0) {
+					displayOutput(" ");
+					displayOutput(myCroreText[1]);
+					displayOutput(" ");
+					passString(num);
+				}
+				numToConvert /= 100;
+				break;
+			case 4:
+				num = numToConvert % 100;
+				if (num != 0) {
+					displayOutput(" ");
+					displayOutput(myCroreText[2]);
+					displayOutput(" ");
+					passString(num);
+				}
+				numToConvert /= 100;
+				break;
+
+			case 5:
+				num = numToConvert % 100;
+				if (num != 0) {
+					displayOutput(" ");
+					displayOutput(myCroreText[3]);
+					displayOutput(" ");
+					passString(num);
+				}
+				numToConvert /= 100;
+				break;
+
+			}
+			in++;
+		}
+		return string.trim();
+	}
+	
+	@Override
+	public Long parse(String text) throws SpellException {
+		return null;
+	}
+
+	private void passString(int number) {
+		int num, q;
+		if (number < 10) {
+			displayOutput(mySingleText[number]);
+		}
+		if (number > 9 && number < 20) {
+			displayOutput(myTeenText[number - 10]);
+		}
+		if (number > 19) {
+			num = number % 10;
+			if (num == 0) {
+				q = number / 10;
+				displayOutput(myCentText[q - 2]);
+			} else {
+				q = number / 10;
+				displayOutput(mySingleText[num]);
+				displayOutput(" ");
+				displayOutput(myCentText[q - 2]);
+			}
+		}
+	}
+
+	private void displayOutput(String s) {
+		StringBuilder sb = new StringBuilder(s);
+		// String t = string;
+		// string = s;
+		sb.append(string);
+		string = sb.toString();
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/PatternDefinition.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/PatternDefinition.java
new file mode 100644
index 0000000..d1d0663
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/PatternDefinition.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+import org.eclipse.uomo.core.IName;
+
+/**
+* A simple class to hold the regular expression sub-definition to validate
+* encoded spelled number.
+* 
+* Remarks: The pattern used to validate the encoded spelled number is long and
+* difficult to be directly created manually. We have used an incremental
+* expandable pattern with $(variable) notation and recursive expansion.
+* 
+* @author Werner Keil
+* 
+* @see {@link SpellContext#generatePattern(String)}
+* @see {@link SpellContext#mySpellPatterns}
+* 
+*/
+class PatternDefinition implements IName {
+
+	/**
+	 * Represents the name of pattern, for example teen in $(teen).
+	 */
+	private String myName;
+
+	/**
+	 * Represents the packed (unexpanded) definition of pattern.
+	 */
+	private String myPackedDefinition;
+
+	/**
+	 * Constructs a new PatternDefinition object with the given name and packed
+	 * definition
+	 * 
+	 * @param name
+	 *            The name or ID of pattern.
+	 * @param packedDefinition
+	 *            The packed (unexpanded) value of pattern.
+	 * 
+	 */
+	public PatternDefinition(String name, String packedDefinition) {
+		this.myName = name;
+		this.myPackedDefinition = packedDefinition;
+	}
+
+	/**
+	 * Gets the name or ID of the pattern variable like varname in $(varname).
+	 * 
+	 * @return the name or ID of pattern.
+	 */
+	public String getName() {
+		return myName;
+	}
+
+	/**
+	 * Gets the packed (unexpanded) value or definition of pattern.
+	 * 
+	 * @return the packed (unexpanded) value or definition of pattern.
+	 */
+	public String getPackedDefinition() {
+		return myPackedDefinition;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/RomanNumberSpeller.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/RomanNumberSpeller.java
new file mode 100644
index 0000000..00fc21a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/RomanNumberSpeller.java
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 1996, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+import org.eclipse.uomo.util.internal.Messages;
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.SpellException;
+
+public class RomanNumberSpeller implements ISpeller {
+	private static final long MAX_ROMAN = 3999;
+	private static RomanNumberSpeller INSTANCE;
+	
+	// singleton
+	private RomanNumberSpeller() {}
+	
+	/**
+	 * @return the default instance
+	 */
+	public static final RomanNumberSpeller of() {
+		if (INSTANCE == null) {
+			INSTANCE = new RomanNumberSpeller();
+		}
+		return INSTANCE;
+	}
+	
+    /**
+     * Converts a decimal number into a Roman number
+     * Valid input in the range 1-3999
+     * Negative values are accepted and returned with a "-" in front.
+     * Zero (0) is returned as an <strong>empty</strong> string ("").
+     * <p>
+     * if the argument is greater than the maximum (3999) an exception is thrown.
+     *
+     */
+	public String spell(final long number) throws SpellException {
+    	if (number > MAX_ROMAN) {
+    		throw new SpellException(Messages.RomanNumberSpeller_0 + MAX_ROMAN);
+    	} else {
+    		return toRoman(number);
+    	}
+    }
+
+    /**
+     * Converts a decimal number into a Roman number
+     * Valid input in the range 1-3999
+     * Negative values are accepted and returned with a "-" in front.
+     * Zero (0) is returned as an <strong>empty</strong> string ("").
+     *
+     */
+    public final String toRoman(long n) {
+        return internalToRoman(n);
+    }
+	
+    /**
+     * Converts a decimal number into a Roman number
+     * Valid input in the range 1-3999
+     * Negative values are accepted and returned with a "-" in front.
+     * Zero (0) is returned as an <strong>empty</strong> string ("").
+     *
+     */
+    public final String toRoman(int n) {
+        return toRoman((long)n);
+    }
+
+    /**
+     * Converts a numeric string into a Roman number
+     * Valid input in the range 1-3999
+     * Negative values are accepted and returned with a "-" in front.
+     * Zero (0) is returned as an <strong>empty</strong> string ("").
+     *
+     */
+    public final String toRoman(String s) {
+        return toRoman(Integer.parseInt(s));
+    }
+    
+    private final String internalToRoman(long number) {
+        final StringBuilder roman = new StringBuilder(""); //$NON-NLS-1$
+        long N = number;
+        while (N >= 1000) {
+              // Move 1000 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_2);
+        	N -= 1000;
+        }
+        while (N >= 900) {
+              // Move 900 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_3);
+        	N -= 900;
+        }
+        while (N >= 500) {
+            // Move 500 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_4);
+        	N -= 500;
+        }
+        while (N >= 400) {
+            // Move 400 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_5);
+        	N -= 400;
+        }
+        while (N >= 100) {
+            // Move 100 from N to roman.
+         roman.append(Messages.RomanNumberSpeller_6);
+         N -= 100;
+        }
+        while (N >= 90) {
+            // Move 90 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_7);
+        	N -= 90;
+        }
+        while (N >= 50) {
+            // Move 50 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_8);
+        	N -= 50;
+        }
+        while (N >= 40) {
+            // Move 40 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_9);
+        	N -= 40;
+        }
+        while (N >= 10) {
+            // Move 10 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_10);
+        	N -= 10;
+        }
+        if (N == 9) {
+            // Move 9 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_11);
+        	N -= 9;
+        }
+        while (N >= 5) {
+            // Move 5 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_12);
+        	N -= 5;
+        }
+        if (N == 4) {
+        	// Move 4 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_13);
+        	N -= 4;
+        }
+        while (N >= 1) {
+            // Move 1 from N to roman.
+        	roman.append(Messages.RomanNumberSpeller_14);
+        	N -= 1;
+        }
+        return roman.toString();
+    }
+	
+	@Override
+	public Long parse(String text) throws SpellException {
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellCode.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellCode.java
new file mode 100644
index 0000000..746ab9c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellCode.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+import org.eclipse.uomo.util.numbers.ISpellCode;
+
+/**
+* The Spell Code implementation
+* 
+* @author Werner Keil
+* 
+* @see {@link ISpellCode}
+* 
+*/
+final class SpellCode implements ISpellCode {
+	/**
+	 * Represents the known word itself.
+	 */
+	private final String myName;
+
+	/**
+	 * Represents the dedicated case-sensitive single-character code for the
+	 * word.
+	 */
+	private final String myCode;
+
+	/**
+	 * Represents the numeric value of the word if it is a word representing a
+	 * value.
+	 */
+	private final Long myValue;
+
+	/**
+	 * Gets the known word representing this code.
+	 * 
+	 * @return the human-readable word or name of the number.
+	 */
+	public String getName() {
+		return myName;
+	}
+
+	/**
+	 * Gets the dedicated case-sensitive single-character code for the word.
+	 * 
+	 * @return the code of the word.
+	 */
+	public String getCode() {
+		return myCode;
+	}
+
+	/**
+	 * Gets the numeric value of the word if it is a word representing a value.
+	 * 
+	 * @return the numeric value equivalent this word.
+	 */
+	public Long getValue() {
+		return myValue;
+	}
+
+	/**
+	 * Constructs a new SpellCode object for a non-numeric word (e.g., minus,
+	 * and, comma or dash).
+	 * 
+	 * @param name
+	 *            the word represented by this code object.
+	 * @param code
+	 *            the code of this word.
+	 */
+	public SpellCode(String name, String code) {
+		myName = name;
+		myCode = code;
+		myValue = Long.valueOf(-1);
+	}
+
+	/**
+	 * Constructs a new SpellCode object for a numeric word (e.g., one, ten,
+	 * hundred, ...)
+	 * 
+	 * @param name
+	 *            the word represented by this code object.
+	 * @param code
+	 *            the code of this word.
+	 * @param value
+	 *            the equivalent numeric value of this word.
+	 */
+	public SpellCode(String name, String code, long value) {
+		myName = name;
+		myCode = code;
+		myValue = Long.valueOf(value);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellContext.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellContext.java
new file mode 100644
index 0000000..e74d3c9
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellContext.java
@@ -0,0 +1,1126 @@
+/**
+ * Copyright (c) 2009, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+/*
+* Maximum value to handle: 9,223,372,036,854,775,807
+* 9223372036854775807
+* Nine Quintillion, Two Hundred and Twenty-Three Quadrillion, Three Hundred and 
+* Seventy-Two Trillion, Thirty-Six Billion, Eight Hundred and Fifty-Four Million, 
+* Seven Hundred and Seventy-Five Thousand, Eight Hundred and Seven
+* 
+*/
+
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.uomo.core.IValidator;
+import org.eclipse.uomo.util.internal.Messages;
+import org.eclipse.uomo.util.numbers.ISpellCode;
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.SpellException;
+
+/**
+* SpellContext is main speller for number spelling, text parsing, encoding
+* and validating.
+* 
+* It contains the following basic static service methods:
+* 
+* <ul>
+* <li>spell (long) : spells a number.
+* <li>parse (String) : parses a spelled text to convert it to an equivalent
+* number (if it is a correct valid number).
+* <li>validate (String) : checks an encoded text to examine if it is a valid
+* text and equivalent to a correctly spelled number.
+* <li>encode (String) : encodes a text string to a concise format suitable to
+* be examined against a regular expression pattern.
+* <li>decode (String) : decodes an encoded text to its human-readable format.
+* <li>encode (long) encodes a long numeric value.
+* <li>decodeToNumder (String) converts an encoded text to its equivalent long
+* numeric value.
+* </ul>
+* TODO change static definitions into OSGi style
+* @author Werner Keil
+*/
+public class SpellContext implements ISpeller, IValidator<String> {
+
+	private static SpellContext INSTANCE;
+	
+	/**
+	 * @return the default instance
+	 */
+	public static SpellContext of() {
+		if (INSTANCE == null) {
+			INSTANCE = new SpellContext();
+		}
+		return INSTANCE;
+	}
+	
+	/**
+	 * Spells a number; converts a number to its equivalent read-out text
+	 * string.
+	 * 
+	 * @param number
+	 *            The number to be spelled.
+	 * 
+	 * @return The word by word read-out of the number - correctly spelled and
+	 *         punctuated.
+	 * 
+	 * @throws SpellException
+	 *             Actually, it is a bug if this method throws an exception.
+	 *             Please report it.
+	 */
+	public String spell(long number) throws SpellException {
+
+		// text holds the intermediate and final result.
+		String text;
+
+		// first check if it is a negative value and adjust the text properly.
+		if (number < 0L) { // if it is negative :
+			// invoke level-one spell and prefix the result with the word: Minus
+			text = Messages.Speller_0 + spell(-number, 1);
+		} else { // otherwise,
+			// simply, invoke level-one spell.
+			text = spell(number, 1);
+		}
+
+		// (see the doc of spell (number, level) for the use and meaning of
+		// level)
+
+		// The resulted text returned from spell (number, level = 1) has some
+		// place-holder characters: '%' and '$'.
+
+		// The place-holder '%' represents where we should place an 'and' in the
+		// spelled text in sub-phrases containing 'hundred'; for example :
+		//
+		// three hundred and twenty-four
+		//
+		// would be like
+		//
+		// three hundred%twenty-four
+		//
+		// a place-holder '%' must always be substituted by ' and ' conjunction
+		// in the final output.
+
+		// The place-holder '$' represents where we should place a comma (,) or
+		// 'and' in the spelled text in sub-phrases containing suffixes:
+		// 'thousand', 'million', 'billion', ...
+
+		// All place-holders '$' save the last one must be substituted by comma
+		// (,). The final place-holder '$' must be substituted by ' and '
+		// conjunction if and only if there is no place-holder '%' after it.
+		// Otherwise, it is substituted by comma, too.
+
+		// The following code before the return statement implements this logic:
+		int index_amp, index_perc;
+
+		index_amp = text.lastIndexOf("$"); //$NON-NLS-1$
+		index_perc = text.lastIndexOf("%"); //$NON-NLS-1$
+
+		if (index_amp >= 0) {
+			if (index_perc < 0 || index_amp > index_perc) {
+
+				String textBeforeAmp = text.substring(0, index_amp);
+				String textAfterAmp = text.substring(index_amp + 1, text
+						.length());
+
+				text = textBeforeAmp + Messages.Speller_3 + textAfterAmp;
+			}
+		}
+
+		text = text.replaceAll(Messages.Speller_4, Messages.Speller_5);
+		text = text.replaceAll("%", Messages.Speller_3); //$NON-NLS-1$
+
+		return text;
+	}
+
+	/**
+	 * Converts the given number to text string. Digits are grouped 3 by 3 and
+	 * separated with thousands-separator character: ','.
+	 * 
+	 * This is a recursive algorithm which could be implemented in all
+	 * languages.
+	 * 
+	 * @param number
+	 *            The number to convert.
+	 * 
+	 * @return the thousand-separated text string equivalent to the given
+	 *         number.
+	 */
+	public static String withSeparatorAlt(long number) {
+		if (number < 0) {
+			return Messages.Speller_8 + withSeparator(-number);
+		}
+
+		if (number / 1000L > 0) {
+			return withSeparator(number / 1000L) + Messages.Speller_9
+					+ String.format("%1$03d", number % 1000L); //$NON-NLS-1$
+		} else {
+			return String.format("%1$d", number); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Converts the given number to text string. Digits are grouped 3 by 3 and
+	 * separated with thousands-separator character: ','.
+	 * 
+	 * This is a Java direct and standard way.
+	 * 
+	 * @param number
+	 *            The number to convert.
+	 * 
+	 * @return the thousand-separated text string equivalent to the given
+	 *         number.
+	 */
+	public static String withSeparator(long number) {
+		return String.format("%1$,d", number); //$NON-NLS-1$
+	}
+
+	/**
+	 * Here, a 'suffix' is a word representing the multiples of thousands.
+	 * 
+	 * mySuffixText is an array of suffixes which could be indexed based on the
+	 * current level of spell.
+	 * 
+	 * @see {@link #spell(long, int)} the implementation of spell (number,
+	 *      level) to check how this array is used.
+	 */
+	private static String mySuffixText[] = {
+			"", // Dummy! no level 0 (added for nicer indexing in code) //$NON-NLS-1$
+			"", // Nothing for level 1 //$NON-NLS-1$
+			Messages.Speller_15, Messages.Speller_16, Messages.Speller_17, Messages.Speller_18, Messages.Speller_19,
+			Messages.Speller_20, };
+
+	/**
+	 * A teen is the word equivalent of numbers [0, 19].
+	 * 
+	 * @see {@link #SpellBelow1000(long)} implementation to check how this array
+	 *      is used.
+	 */
+	private static String myTeenText[] = { Messages.Speller_21, Messages.Speller_22, Messages.Speller_23, Messages.Speller_24,
+			Messages.Speller_25, Messages.Speller_26, Messages.Speller_27, Messages.Speller_28, Messages.Speller_29, Messages.Speller_30, Messages.Speller_31, Messages.Speller_32,
+			Messages.Speller_33, Messages.Speller_34, Messages.Speller_35, Messages.Speller_36, Messages.Speller_37,
+			Messages.Speller_38, Messages.Speller_39, Messages.Speller_40, };
+
+	/**
+	 * A cent has two meanings in this project: it is either any value below one
+	 * hundred, or it is the multiples of ten bellow one hundred.
+	 * 
+	 * @see {@link #SpellBelow1000(long)} implementation to check how this array
+	 *      is used.
+	 */
+	private static String myCentText[] = { Messages.Speller_41, Messages.Speller_42, Messages.Speller_43,
+			Messages.Speller_44, Messages.Speller_45, Messages.Speller_46, Messages.Speller_47, Messages.Speller_48 };
+
+	/**
+	 * Formal English requires to use hyphen between a cent and digit; for
+	 * example, 21 is correctly spelled as twenty-one.
+	 * 
+	 * usingCentHyphen (static public data property) controls the behavior of
+	 * this class whether to use hyphen after a cent/digit combination or not.
+	 */
+	public static boolean usingCentHyphen = false;
+
+	/**
+	 * For internal use. Decides whether to use a hyphen or space for cent-digit
+	 * combination.
+	 * 
+	 * @return hyphen or space based on the current global setting.
+	 */
+	private static String centHyphen() {
+		return usingCentHyphen ? Messages.Speller_49 : " "; //$NON-NLS-2$
+	}
+
+	/**
+	 * Spells a mil value. A mil is any value below one thousand ([0, 999]).
+	 * 
+	 * @param number
+	 *            the number (< 1000) to be spelled.
+	 * @return the spelled text.
+	 * @throws SpellException
+	 *             if number is negative or it is greater than or equals to
+	 *             1000.
+	 */
+	private static String SpellBelow1000(long number) throws SpellException {
+		// if number is negative or above 999, throw a SpellException.
+		if (number < 0 || number >= 1000)
+			throw new SpellException(Messages.Speller_51
+					+ number);
+
+		if (number < 20L) {
+			// if number is a teen,
+			// find it in teen table and return its equivalent text (word).
+			return myTeenText[(int) number];
+		} else if (number < 100L) {
+			// otherwise, if it is a cent,
+			// find the most (div) and least (rem) significant digits (MSD/LSD)
+			int div = (int) number / 10;
+			int rem = (int) number % 10;
+
+			if (rem == 0) {
+				// if LSD is zero, return the cent key word directly (like
+				// fifty).
+				return myCentText[div - 2];
+			} else {
+				// otherwise, return the text as cent-teen (like fifty-one)
+				return myCentText[div - 2] + centHyphen() + myTeenText[rem];
+			}
+		} else {
+			// otherwise, it is a mil;
+			// find it's MSD and remaining cent.
+			int div = (int) number / 100;
+			int rem = (int) number % 100;
+
+			// Prepare the mil prefix:
+			String milText = myTeenText[div] + Messages.Speller_52;
+
+			// decide whether to append the cent tail or not.
+			if (rem == 0) {
+				// if it does have a non-zero cent, that's it.
+				// return the mil prefix, for example three hundred:
+				return milText;
+			} else {
+				// otherwise, spell the cent and append it to mil prefix.
+				// (now, rem is a cent).
+				// '%' is a place-holder which will eventually converted to
+				// ' and ' conjunction in final output string. It cannot be done
+				// right here, because we would need it in conjunction with
+				// another place-holder: '$' to properly set all the punctuation
+				// properly.
+				// For example, three Hundred%Sixty-Four:
+				return milText + "%" + SpellBelow1000(rem); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Spells the number based on successive (recursive) division by 1000.
+	 * Starting from 1, each division increments the level of evaluation which
+	 * is passed to next nested level of recursion.
+	 * 
+	 * Level helps to use the appropriate suffix for the spelled sub-value.
+	 * 
+	 * @param number
+	 *            the (sub-) number to be spelled.
+	 * @param level
+	 *            The current level of evaluation.
+	 * @return the spell text equivalent to the (sub-) number and its level.
+	 * @throws SpellException
+	 *             Actually, it is a bug if this method throws an exception.
+	 *             Exceptions happens if the method SpellBelow1000 (long) is
+	 *             called for an out-of-ranged value (negative or above 999)
+	 *             which should never happen in this algorithm.
+	 */
+	private static String spell(long number, int level) throws SpellException {
+		// first, find the normed over-mil value (div) and the remaining mil
+		// value (rem).
+		long div = number / 1000L;
+		long rem = number % 1000L;
+
+		// check if over-mil value is zero:
+		if (div == 0) {
+			// if it is, then it is a mil value [0, 999];
+			// spell it and append the right suffix based on the current level.
+			return SpellBelow1000(rem) + mySuffixText[level];
+		} else {
+			// otherwise, increment the level for the over-mil value and spell
+			// it; append the spell of mil portion if it is non-zero.
+			// '$' is a place-holder which will eventually be converted to
+			// either comma (,) or ' and ' conjunction. The decision about which
+			// one should be taken cannot be made here, but after the original
+			// number is fully spelled. See the comment in the implementation of
+			// spell (long) to check how this decision is made.
+
+			if (rem == 0) {
+				return spell(div, level + 1);
+			} else {
+				return spell(div, level + 1) + "$" + SpellBelow1000(rem) //$NON-NLS-1$
+						+ mySuffixText[level];
+			}
+		}
+	}
+
+	/**
+	 * Examines the given text to check if it is a single number word
+	 * corresponding to a value below 1000.
+	 * 
+	 * @param text
+	 *            The text under examination.
+	 * @return true if the text is a single number word corresponding to a value
+	 *         below 1000.
+	 */
+	private static boolean isBelowThousandWord(String text) {
+		// simply, check the dictionary: myNameMap
+
+		if (!myNameMap.containsKey(text))
+			return false;
+
+		long value = myNameMap.get(text).getValue().longValue();
+
+		return value >= 0L && value < 1000L;
+	}
+
+	/**
+	 * Parses a mil text. If the given text is the spelled text equivalent to a
+	 * mil number [0, 999], this method would return that number.
+	 * 
+	 * This method is extremely tolerant. If the spelled number (text) contains
+	 * all valid mil words (words corresponding to a single number less than
+	 * 1000), it would return some value (intended or unintended) any way. It
+	 * works correctly for correctly spelled mil text.
+	 * 
+	 * @param text
+	 *            The text to be parsed.
+	 * @return the number equivalent to the text.
+	 * @throws SpellException
+	 *             if the text is not a valid mil text.
+	 * 
+	 */
+	private static long parseBelow1000(String text) throws SpellException {
+
+		// The algorithm is fairly simple;
+
+		// Initially, assume value is zero.
+		long value = 0;
+
+		// The only valid punctuation is ' and ' conjunction. It senses only for
+		// human read.
+		// It has no use here. simple remove them. This algorithm is tolerant,
+		// we do not validate the text here.
+		// Then, split the text to words.
+		String[] words = text.replaceAll(Messages.Speller_55, " ").split("\\s+"); //$NON-NLS-2$ //$NON-NLS-3$
+
+		// Now, for each word in text:
+		for (String word : words) {
+			// check if the word is a mil word.
+			// throw exception if it is not.
+			if (!isBelowThousandWord(word)) {
+				throw new SpellException(Messages.Speller_58 + word);
+			}
+
+			// get the nominal value of the mil word.
+			long subval = getValueOf(word);
+
+			// if it is the word "hundred" (value == 100),
+			if (subval == 100) {
+				// based on the previous evaluated value,
+				if (value == 0)
+					// either set it to 100 (the previous value was 0).
+					value = 100;
+				else
+					// or multiply it by 100.
+					value *= 100;
+			} else
+				// otherwise, simply add it to the value (whatever it is, and
+				// whatever previously parsed for value)
+				value += subval;
+
+		}
+
+		// return the evaluated value.
+		return value;
+	}
+
+	/**
+	 * Gets the value equivalent to a single-word spelled number.
+	 * 
+	 * @param word
+	 *            a single-word spelled number.
+	 * @return the equivalent value.
+	 */
+	private static long getValueOf(String word) {
+
+		// simply look-up the word in dictionary: myNameMap.
+		return myNameMap.get(word).getValue().longValue();
+	}
+
+	/**
+	 * Suffixes used in spelling (and parsing) a word.
+	 * 
+	 * @see {@link #parseInternal(String)} to check how this array is used.
+	 */
+	private final static String[] mySuffixWords = { Messages.Speller_59,
+			Messages.Speller_60, Messages.Speller_61, Messages.Speller_62, Messages.Speller_63, Messages.Speller_64 };
+
+	/**
+	 * The equivalent numeric value of suffixes used in spelling (and parsing) a
+	 * word.
+	 * 
+	 * @see {@link #mySuffixWords} This array matches mySuffixWords element by
+	 *      element.
+	 * @see {@link #parseInternal(String)} to check how this array is used.
+	 */
+	private final static long[] mySuffixValues = { 1000000000000000000L,
+			1000000000000000L, 1000000000000L, 1000000000L, 1000000L, 1000L };
+
+	/**
+	 * For public use: parses a human-readable spelling text of a number, and
+	 * converts it to the corresponding numeric value.
+	 * 
+	 * @param text
+	 *            the human-readable spelling text of a number.
+	 * @return the numeric value corresponding to the human-readable number
+	 *         text.
+	 * @throws SpellException
+	 *             if the text contains intolerable, misplaced or unknown word.
+	 * 
+	 *@see {@link #parseInternal(String)} which does a similar operation with
+	 *      text not possibly started with word ''minus''. Actually, it does the
+	 *      main operation.
+	 */
+	public Long parse(String text) throws SpellException {
+
+		// remove all punctuation.
+		text = toFriendlyString(text);
+
+		// if the text starts with word: ''minus''.
+		if (text.startsWith(Messages.Speller_65)) {
+			// extract substring after ''minus''
+			String subtext = text.substring(Messages.Speller_66.length());
+
+			// It must not be empty and must not be started with a none-white
+			// character
+			if (subtext.equals("") //$NON-NLS-1$
+					|| !Character.isWhitespace(subtext.charAt(0))) {
+
+				// if it is, throw exception.
+				throw new SpellException(Messages.Speller_68
+						+ text);
+			}
+
+			// If it is OK, parse the substring after ''minus'' and negate the
+			// evaluated value.
+			return -parseInternal(subtext.trim());
+		} else {
+			// If it is not started with ''minus'', simply parse it, and return
+			// the evaluated value.
+			return parseInternal(text);
+		}
+	}
+
+	/**
+	 * For internal use only: parses a human-readable spelling text of a number,
+	 * and converts it to the corresponding numeric value.
+	 * 
+	 * The algorithm works recursively this way: It looks for known suffixes
+	 * like: ''thousand'', ''million'', ... (of course, in reversed order). If
+	 * it found one, It parses the substring before it as a mil text (a spelled
+	 * number text below 1000), and it calls itself once more for the substring
+	 * after the suffix.
+	 * 
+	 * If the substring before suffix is empty (like 'thousand and twenty
+	 * three'), then it assumes 'one' ('one thousand and twenty three').
+	 * 
+	 * If the substring after suffix is empty (like 'two thousand'), then it
+	 * assumes 'zero' ('two thousand and zero').
+	 * 
+	 * If the text does not have any suffix, it parses it as a mil text (a value
+	 * below 1000).
+	 * 
+	 * @param text
+	 *            the human-readable spelling text of a number.
+	 * @return the numeric value corresponding to the human-readable number
+	 *         text.
+	 * @throws SpellException
+	 *             if the text contains intolerable, misplaced or unknown word.
+	 */
+	private static long parseInternal(String text) throws SpellException {
+
+		// First, assume the evaluated value is zero.
+		long totalValue = 0;
+
+		// Also, first assume that there is no suffix in the text.
+		boolean suffixFound = false;
+
+		// Examines all suffixed from biggest to lowest:
+		// Check if the text contain a suffix:
+		for (int n = 0; n < mySuffixWords.length; n++) {
+
+			// look for the next suffix.
+			int index = text.indexOf(mySuffixWords[n]);
+
+			// If it has a suffix,
+			if (index >= 0) {
+				// Extract substrings before and after suffix.
+				String textBeforeSuffix = text.substring(0, index).trim();
+				String textAfterSuffix = text.substring(
+						index + mySuffixWords[n].length()).trim();
+
+				// if the substring before suffix is empty, assume 'one'.
+				if (textBeforeSuffix.equals("")) //$NON-NLS-1$
+					textBeforeSuffix = Messages.Speller_70;
+
+				// if the substring after suffix is empty, assume 'zero'.
+				if (textAfterSuffix.equals("")) //$NON-NLS-1$
+					textAfterSuffix = Messages.Speller_72;
+
+				// parse both substrings properly, and evaluate the total value.
+				totalValue = parseBelow1000(textBeforeSuffix)
+						* mySuffixValues[n] + parseInternal(textAfterSuffix);
+
+				// mark 'suffix is found'.
+				suffixFound = true;
+
+				// no need to look for another suffix, they are done in
+				// recursive loops. End the loop.
+				break;
+			}
+
+			// If the text does not have this suffix, check next suffix.
+		}
+
+		// check if there was a suffix in the text.
+		if (suffixFound)
+			// If there is a suffix, the total value has already been evaluated,
+			// return it:
+			return totalValue;
+		else
+			// Otherwise, parse it as a mil text (a spelled number text below
+			// 1000).
+			return parseBelow1000(text);
+	}
+
+	/**
+	 * Removes usual punctuation from a spelled number text. The SpellContext
+	 * parser does not need the punctuation, and they are normally useful only
+	 * for human-readability.
+	 * 
+	 * @param text
+	 *            The text containing punctuation.
+	 * @return The text without punctuation.
+	 */
+	private static String toFriendlyString(String text) {
+		return text.toLowerCase().replaceAll("[\\-,]", " ").replaceAll(Messages.Speller_3, //$NON-NLS-1$ //$NON-NLS-2$
+				" ").trim(); //$NON-NLS-1$
+	}
+
+	/**
+	 * Represent the desired behavior of the encode/decode method when
+	 * encountering an error.
+	 */
+	public static enum CodingErrorBehavior {
+		SPECIAL_TOKEN, EXCEPTION;
+	}
+
+	/**
+	 * Represent the desired action of the encode/decode method when
+	 * encountering an error.
+	 */
+	public static CodingErrorBehavior codingErrorAction = CodingErrorBehavior.SPECIAL_TOKEN;
+
+	/**
+	 * Encodes a spelled number text to a unique string containing predefined
+	 * single character for each known (recognize) token of the text.
+	 * 
+	 * @param text
+	 *            The spelled number text to be encoded
+	 * @return The encoded string
+	 * @throws SpellException
+	 *             if the codingErrorAction is set to be Exception and the text
+	 *             contains some unknown token.
+	 * 
+	 * @see {@link SpellCode} the class containing the definition for each known
+	 *      token.
+	 * @see {@link CodingErrorBehavior} and
+	 * @see {@link codingErrorAction}
+	 * @see {@link SpellContext#decode(String)}
+	 */
+	/**
+	 * @param text
+	 * @return
+	 * @throws SpellException
+	 */
+	public static String encode(String text) throws SpellException {
+		/**
+		 * In this project, we have used a unique way of encoding spelled number
+		 * to a string. Each known word (or punctuation) in a spelled number
+		 * string is converted to a case-sensitive single-character code. For
+		 * example, the spelled number:
+		 * 
+		 * Two Thousand, Three Hundred and Nine (2,309)
+		 * 
+		 * is encoded as:
+		 * 
+		 * 2T,3I&9
+		 * 
+		 * In this encoding,
+		 * 
+		 * 2 represents the word: "two", T represents the word: :thousand",
+		 * Comma (,) represents itself, 3 represents the word: "three", I
+		 * represents the word: "hundred", ampersand (&) represents the word:
+		 * "and", and finally, 9 represents the word nine.
+		 * 
+		 * The great advantage of this encoding is that it would be fairly easy
+		 * to validate a text as being a correct spelled number using regular
+		 * expression.
+		 * 
+		 * SpellCode class is a way to hold encoding and recognition information
+		 * for a single known word in spelling contexts. These are words like
+		 * thousand, fourteen etc which all have a name (e.g., fourteen), a
+		 * dedicated case-sensitive single-character code (U) and an associative
+		 * value (14).
+		 */
+
+		// first, make the text case-insensitive.
+		text = text.toLowerCase();
+
+		// The pattern to extract known tokens, It is either dash (-) or comma
+		// (,) (first group), an identifier (second group), or others (a string
+		// of one or more punctuation characters) (other)
+		Pattern pat = Pattern.compile("(?:[\\-,]|\\w+|\\S+)"); //$NON-NLS-1$
+
+		// match the text against pattern.
+		Matcher m = pat.matcher(text);
+
+		// a string builder to hold the encoded the string.
+		StringBuilder sb = new StringBuilder();
+
+		// know search the text for the known tokens:
+		while (m.find()) {
+			// If still there is a token,
+			String token = m.group();
+
+			// look it up in dictionary : myNamemap.
+			if (myNameMap.containsKey(token)) {
+				// If it is in dictionary, append its code to the string
+				sb.append(myNameMap.get(token).getCode());
+			} else {
+				// otherwise,
+
+				// If the desired action is to insert special error token,
+				if (codingErrorAction == CodingErrorBehavior.SPECIAL_TOKEN)
+					// append a special error token to the string.
+					sb.append('#');
+				else
+					// otherwise, the desired action is exception, throw it.
+					throw new SpellException(Messages.Speller_78 + token);
+			}
+		}
+
+		// convert the encoded string builder to string and return it.
+		return sb.toString();
+
+	}
+
+	/**
+	 * Decodes an encoded string back to a human-readable spelled number text.
+	 * 
+	 * @param text
+	 *            The encoded text.
+	 * @return a human-readable spelled number text representing the encoded
+	 *         number.
+	 * @throws SpellException
+	 *             if the codingErrorAction is set to be Exception and the
+	 *             encoded text contains a special token representing some
+	 *             unknown token.
+	 * 
+	 * @see {@link SpellCode} the class containing the definition for each known
+	 *      token.
+	 * @see {@link CodingErrorBehavior} and
+	 * @see {@link codingErrorAction}
+	 * @see {@link SpellContext#encode(String)}
+	 */
+	public static String decode(String text) throws SpellException {
+
+		// a string builder to hold the final decoded string.
+		StringBuilder sb = new StringBuilder();
+
+		// represent the last token; used to decide when to prefix a token with
+		// a space.
+		String lastToken = null;
+
+		// scan all encoded characters in the input string
+		for (char c : text.toCharArray()) {
+
+			// find the code in dictionary : myCodeMap.
+			ISpellCode sc = myCodeMap.get(Character.toString(c));
+			String token;
+
+			// if there is no code for this encoded character,
+			if (sc == null) {
+				// depending on the current desired code error behavior,
+				if (codingErrorAction == CodingErrorBehavior.SPECIAL_TOKEN)
+					// either append a special token,
+					token = "(?)"; //$NON-NLS-1$
+				else
+					// or throw an exception.
+					throw new SpellException(
+							Messages.Speller_80 + c);
+			} else
+				// otherwise, if there is a code in dictionary, read its token
+				// word.
+				token = sc.getName();
+
+			// If there is no last token, or the last token and this tokens are
+			// not hyphen, and also this token is not comma,
+			if (lastToken != null && !lastToken.equals(Messages.Speller_81)
+					&& !token.equals(Messages.Speller_82) && !token.equals(Messages.Speller_83)) {
+
+				// append a space before token.
+				sb.append(' ');
+			}
+
+			// append the token.
+			sb.append(token);
+
+			// for next loop, mark the last token as this token.
+			lastToken = token;
+		}
+
+		// convert builder to string and return it.
+		return sb.toString();
+	}
+
+	/**
+	 * Converts a number directly to encoded string.
+	 * 
+	 * @param number
+	 *            The number to be encoded.
+	 * @return The encoded string representing the given number.
+	 * @throws SpellException
+	 *             Actually, there is no error ever in directly encoding a
+	 *             numeric value.
+	 */
+	public static String encode(long number) throws SpellException {
+		return encode(of().spell(number));
+	}
+
+	/**
+	 * Decodes an encoded text directly to its numeric value.
+	 * 
+	 * @param text
+	 *            The encoded text to be decoded.
+	 * @return The numeric value corresponding the given encoded text.
+	 * @throws SpellException
+	 *             if the codingErrorAction is set to be Exception and the
+	 *             encoded text contains a special token representing some
+	 *             unknown token.
+	 */
+	public static long decodeToNumber(String text) throws SpellException {
+		return of().parse(decode(text)).longValue();
+	}
+
+	/**
+	 * The array containing all single character codes dedicated to known spell
+	 * number word.
+	 */
+	private static ISpellCode[] myCodes = {
+	// First element
+
+			// Zero
+			new SpellCode(Messages.Speller_84, "0", 0L), //$NON-NLS-2$
+
+			// One
+			new SpellCode(Messages.Speller_86, "1", 1L), //$NON-NLS-2$
+
+			// Two
+			new SpellCode(Messages.Speller_88, "2", 2L), //$NON-NLS-2$
+
+			// Three
+			new SpellCode(Messages.Speller_90, "3", 3L), //$NON-NLS-2$
+
+			// Four
+			new SpellCode(Messages.Speller_92, "4", 4L), //$NON-NLS-2$
+
+			// Five
+			new SpellCode(Messages.Speller_94, "5", 5L), //$NON-NLS-2$
+
+			// Six
+			new SpellCode(Messages.Speller_96, Messages.Speller_97, 6L),
+
+			// Seven
+			new SpellCode(Messages.Speller_98, "7", 7L), //$NON-NLS-2$
+
+			// Eight
+			new SpellCode(Messages.Speller_100, "8", 8L), //$NON-NLS-2$
+
+			// Nine
+			new SpellCode(Messages.Speller_102, "9", 9L), //$NON-NLS-2$
+
+			// Ten
+			new SpellCode(Messages.Speller_104, "R", 10L), //$NON-NLS-2$
+
+			// Eleven
+			new SpellCode(Messages.Speller_106, "P", 11L), //$NON-NLS-2$
+
+			// Twelve
+			new SpellCode(Messages.Speller_108, "Q", 12L), //$NON-NLS-2$
+
+			// Thirteen
+			new SpellCode(Messages.Speller_110, "K", 13L), //$NON-NLS-2$
+
+			// Fourteen
+			new SpellCode(Messages.Speller_112, "U", 14L), //$NON-NLS-2$
+
+			// Fifteen
+			new SpellCode(Messages.Speller_114, "Y", 15L), //$NON-NLS-2$
+
+			// Sixteen
+			new SpellCode(Messages.Speller_116, "A", 16L), //$NON-NLS-2$
+
+			// Seventeen
+			new SpellCode(Messages.Speller_118, "B", 17L), //$NON-NLS-2$
+
+			// Eighteen
+			new SpellCode(Messages.Speller_120, "C", 18L), //$NON-NLS-2$
+
+			// Nineteen
+			new SpellCode(Messages.Speller_122, "D", 19L), //$NON-NLS-2$
+
+			// Twenty
+			new SpellCode(Messages.Speller_124, "H", 20L), //$NON-NLS-2$
+
+			// Thirty
+			new SpellCode(Messages.Speller_126, "S", 30L), //$NON-NLS-2$
+
+			// Forty
+			new SpellCode(Messages.Speller_128, "F", 40L), //$NON-NLS-2$
+
+			// Fifty
+			new SpellCode(Messages.Speller_130, "E", 50L), //$NON-NLS-2$
+
+			// Sixty
+			new SpellCode(Messages.Speller_132, "X", 60L), //$NON-NLS-2$
+
+			// Seventy
+			new SpellCode(Messages.Speller_134, "V", 70L), //$NON-NLS-2$
+
+			// Eighty
+			new SpellCode(Messages.Speller_136, "G", 80L), //$NON-NLS-2$
+
+			// Ninety
+			new SpellCode(Messages.Speller_138, "N", 90L), //$NON-NLS-2$
+
+			// Hundred
+			new SpellCode(Messages.Speller_140, "I", 100L), //$NON-NLS-2$
+
+			// Thousand
+			new SpellCode(Messages.Speller_142, "T", 1000L), //$NON-NLS-2$
+
+			// Million
+			new SpellCode(Messages.Speller_144, "M", 1000000L), //$NON-NLS-2$
+
+			// Billion
+			new SpellCode(Messages.Speller_146, "J", 1000000000L), //$NON-NLS-2$
+
+			// Trillion
+			new SpellCode(Messages.Speller_148, "L", 1000000000000L), //$NON-NLS-2$
+
+			// Quadrillion
+			new SpellCode(Messages.Speller_150, "W", 1000000000000000L), //$NON-NLS-2$
+
+			// Quintillion
+			new SpellCode(Messages.Speller_152, "Z", 1000000000000000000L), //$NON-NLS-2$
+
+			// and
+			new SpellCode(Messages.Speller_154, "&"), //$NON-NLS-2$
+
+			// Minus
+			new SpellCode(Messages.Speller_156, "-"), //$NON-NLS-2$
+
+			// Comma
+			new SpellCode(Messages.Speller_158, ","), //$NON-NLS-2$
+
+			// dash
+			new SpellCode(Messages.Speller_160, "_"), //$NON-NLS-2$
+
+	// last element
+	}; // private static SpellCode[] myCodes
+
+	/**
+	 * The array containing the known and acceptable encoded patterns for all
+	 * numeric values. The patterns are in the packed format which will be
+	 * expanded to regular expression.
+	 * 
+	 * @see {@link #generatePattern(String)} the method which expands a pattern
+	 *      definition from its packed format to ultimate regular expression.
+	 * 
+	 * @see {@link #myCodes} to check how categories: 'digit', 'odig', 'teen'
+	 *      and 'oteen' are interpreted.
+	 */
+	private static PatternDefinition[] mySpellPatterns = {
+			// SpellPattern begin
+
+			// pattern name
+			new PatternDefinition("zero", "0"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("digit", Messages.Speller_165), //$NON-NLS-1$
+			new PatternDefinition(Messages.Speller_166, "[RPQKUYA-D]"), //$NON-NLS-2$
+			new PatternDefinition("teen", "$(digit)|$(odig)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oteen", "[HSFEXVGN](_?$(digit))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("cent", "$(teen)|$(oteen)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("ocent", "$(digit)I(&?$(cent))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("mil", "$(cent)|$(ocent)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("omil", "$(mil)T([,&]?$(mil))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e3", "$(mil)|$(omil)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oe3", "$(mil)M([,&]?$(e3))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e6", "$(e3)|$(oe3)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oe6", "$(mil)J([,&]?$(e6))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e9", "$(e6)|$(oe6)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oe9", "$(mil)L([,&]?$(e9))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e12", "$(e9)|$(oe9)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oe12", "$(mil)W([,&]?$(e12))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e15", "$(e12)|$(oe12)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("oe15", "$(mil)Z([,&]?$(e15))?"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("e18", "$(e15)|$(oe15)"), //$NON-NLS-1$ //$NON-NLS-2$
+			new PatternDefinition("num", "\\-?$(zero)|\\-?$(e18)"), //$NON-NLS-1$ //$NON-NLS-2$
+
+	// SpellPattern end
+	};
+
+	/**
+	 * Represents a dictionary mapping a known spell word to its coding
+	 * information.
+	 */
+	private static HashMap<String, ISpellCode> myNameMap;
+
+	/**
+	 * Represents a dictionary mapping a known spell single-character code to
+	 * its coding information.
+	 */
+	private static HashMap<String, ISpellCode> myCodeMap;
+
+	/**
+	 * Represents a dictionary mapping a pattern variable name to its packed
+	 * format definition.
+	 */
+	private static HashMap<String, PatternDefinition> mySpellPatternMap;
+
+	/**
+	 * Holds the ultimate regular expression pattern to validate all encoded
+	 * spelled number texts. It is the expanded value of the final pattern
+	 * definition.
+	 */
+	private static String myNumberPattern;
+
+	/**
+	 * Initializes all definition and information arrays and dictionary which
+	 * could not be done at declaration point.
+	 * 
+	 * @return a dummy true to set a dummy myInit static boolean variable.
+	 */
+	private static boolean init() {
+		// Initialize dictionaries:
+		myNameMap = new HashMap<String, ISpellCode>();
+		myCodeMap = new HashMap<String, ISpellCode>();
+		mySpellPatternMap = new HashMap<String, PatternDefinition>();
+
+		// Load dictionary data : myNameMap and myCodeMap
+		for (ISpellCode sc : myCodes) {
+			myNameMap.put(sc.getName().toLowerCase(), sc);
+			myCodeMap.put(sc.getCode(), sc);
+		}
+
+		// load dictionary data : mySpellPatternMap
+		for (PatternDefinition pd : mySpellPatterns) {
+			mySpellPatternMap.put(pd.getName(), pd);
+
+		}
+
+		// expand ultimate regular expression pattern to validate encoded
+		// spelled number texts.
+		try {
+			myNumberPattern = "^\\-?" + generatePattern("num") + "$"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		} catch (SpellException e) {
+			e.printStackTrace();
+		}
+
+		return true;
+	}
+
+	/**
+	 * Validates the given encoded text as being a correctly spelled number with
+	 * a valid grammar. Always throws exception on validation failure.
+	 * 
+	 * @param encodedText
+	 *            The encoded text to be validated.
+	 * @throws SpellException
+	 *             if the encoded text is not a valid encoded spelled number.
+	 */
+	public void validate(String encodedText) throws SpellException {
+		// Simply, compile the pattern.
+		Pattern pat = Pattern.compile(myNumberPattern);
+
+		// match the given encoded spelled number against the validation
+		// pattern.
+		Matcher mat = pat.matcher(encodedText);
+
+		// If not matches, throw exception.
+		if (!mat.matches()) {
+			throw new SpellException(Messages.Speller_207 + encodedText);
+		}
+	}
+
+	/**
+	 * Generates a regular expression pattern from its pattern-definition name
+	 * from its packed definition by recursive expansion of all other packed
+	 * definition inside it.
+	 * 
+	 * @param name
+	 *            The name of the pattern to expand.
+	 * @return The regular expression expanded definition.
+	 * @throws SpellException
+	 *             if the definition with the given name does exist.
+	 */
+	private static String generatePattern(String name) throws SpellException {
+
+		// first check if the name exists in dictionary.
+		if (!mySpellPatternMap.containsKey(name))
+			// if not exists, throw exception.
+			throw new SpellException(Messages.Speller_208
+					+ name);
+
+		// get the pattern.
+		PatternDefinition pd = mySpellPatternMap.get(name);
+
+		// get the nested definitions inside the definition:
+
+		// The reg-exp pattern to extract variable names in definition.
+		Pattern pat = Pattern.compile("\\$\\((\\w+)\\)"); //$NON-NLS-1$
+
+		// match the packed format definition against the reg-exp for variable
+		// name.
+		Matcher mat = pat.matcher(pd.getPackedDefinition());
+		String output = pd.getPackedDefinition();
+
+		// while there is a nested variable name in the packed definition,
+		while (mat.find()) {
+
+			// expand it recursively,
+
+			// Get the var name.
+			String varName = mat.group(1);
+
+			// create the replacement text
+			String repText = String.format("\\$\\(%1$s\\)", varName); //$NON-NLS-1$
+
+			// Get the value corresponding the var name.
+			String value = String.format("(?:%1$s)", generatePattern(mat //$NON-NLS-1$
+					.group(1)));
+
+			// replace the packed definition variable with its equivalent
+			// expanded value.
+			output = output.replaceAll(repText, value);
+		}
+
+		// return the ultimately expanded reg-exp;
+		return output;
+	}
+
+	/**
+	 * A dummy variable to ensure that all static arrays and dictionaries are
+	 * initialized before first use. Not used anywhere in code. It just makes
+	 * sure that {@link #init()} has been invoked once and for all.
+	 */
+	@SuppressWarnings("unused")
+	private static boolean myInit = init();
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellServiceImpl.java b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellServiceImpl.java
new file mode 100644
index 0000000..8e4227c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/java/org/eclipse/uomo/util/numbers/impl/SpellServiceImpl.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.util.numbers.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uomo.util.numbers.ISpeller;
+import org.eclipse.uomo.util.numbers.SpellService;
+
+public class SpellServiceImpl implements SpellService {
+
+	private final List<ISpeller> spellers = new ArrayList<ISpeller>();
+
+	@Override
+	public void registerSpeller(ISpeller speller) {
+		spellers.add(speller);
+	}
+
+	@Override
+	public void unregisterSpeller(ISpeller speller) {
+		spellers.remove(speller);
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/errors.properties b/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/errors.properties
new file mode 100644
index 0000000..7f50a05
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/errors.properties
@@ -0,0 +1,7 @@
+UOMoNumberFormatException.INTERNAL_ERROR = INTERNAL ERROR
+UOMoNumberFormatException.NINF           = NINF
+UOMoNumberFormatException.NaN            = NaN
+UOMoNumberFormatException.PINF           = PINF
+UOMoNumberFormatException.RULE           = RULE
+UOMoNumberFormatException.SIZE           = SIZE
+UOMoNumberFormatException.TEXT_FORMAT     = text format
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/messages.properties b/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/messages.properties
new file mode 100644
index 0000000..b354e13
--- /dev/null
+++ b/bundles/org.eclipse.uomo.util/src/main/resources/org/eclipse/uomo/util/messages.properties
@@ -0,0 +1,247 @@
+Iso8601Date_58=TT[tt]
+Iso8601Date_59=No Timezone allowed, but a timezone found
+Iso8601Date_60=No Timezone allowed, but a timezone found
+Iso8601Date_61=Error occurred reading date: '
+Iso8601Date_62=': 
+Iso8601Date_63=]
+Iso8601Date_65=[
+Iso8601Date_66="
+Iso8601Date_67=" is not valid for the section 
+Iso8601Date_68=The section 
+Iso8601Date_69=\ in the Date format 
+Iso8601Date_70=\ was not found in the value 
+Iso8601Date_71=The section 
+Iso8601Date_72=\ in the Date format 
+Iso8601Date_73=\ was not completed in the value 
+Iso8601Date_74=\ - value was 
+Iso8601Date_75=The content 
+Iso8601Date_76=\ in the Date 
+Iso8601Date_77=\ is not allowed by the format 
+Iso8601Date_HH=HH
+Iso8601Date_TT=TT
+Iso8601Date_DATE_FRAGMENT_NOT_KNOWN=The Date Format fragment 
+Iso8601Date_day=day
+Iso8601Date_DAY_VALUE_ILLEGAL_FOR_MONTH=Day Value 
+Iso8601Date_DAY_VALUE_MONTH_MUST_BE_KNOWN=Day Value 
+Iso8601Date_DAY_VALUE_MUST_BE_POSITIVE=Day Value 
+Iso8601Date_DAY_VALUE_NOT_2_DIGITS=Day Value 
+Iso8601Date_DAY_VALUE_NOT_NUMERICAL=Day Value 
+Iso8601Date_DAY_VALUE_YEAR_MUST_BE_KNOWN=Day Value 
+Iso8601Date_DAYS=days
+Iso8601Date_dd=dd
+Iso8601Date_DD=DD
+Iso8601Date_DEF_OUTPUT_FORMAT=YYYYMMDDHHNNSS.SSS
+Iso8601Date_DOT=.
+Iso8601Date_EXPECTED_DOT=Expected '.'
+Iso8601Date_FRACT_VAL_NOT_NUMERICAL=Fraction Value 
+Iso8601Date_GMT=GMT
+Iso8601Date_hh=hh
+Iso8601Date_hour=hour
+Iso8601Date_HOUR_VALUE_MUST_BE_0_OR_POSITIVE=Hour Value 
+Iso8601Date_HOUR_VALUE_MUST_BE_12_OR_LESS=Hour Value 
+Iso8601Date_HOUR_VALUE_NOT_2_DIGITS=Hour Value 
+Iso8601Date_HOUR_VALUE_NOT_NUMERICAL=Hour Value 
+Iso8601Date_HOURS=hours
+Iso8601Date_ISO_DATE_VALIDATION_DATE=YYYY[MM[DD]]]
+Iso8601Date_ISO_DATE_VALIDATION_FULL=YYYY[MM[DD[HH[NN[SS[.U[U[U[U]]]]]]]]]
+Iso8601Date_MILIS=millseconds
+Iso8601Date_milisecond=millisecond
+Iso8601Date_MINUS=-
+Iso8601Date_minute=minute
+Iso8601Date_MINUTE_VALUE_MUST_BE_0_AND_59=Minute Value 
+Iso8601Date_MINUTE_VALUE_NOT_2_DIGITS_LONG=Minute Value 
+Iso8601Date_MINUTE_VALUE_NOT_NUMERICAL=Minute Value 
+Iso8601Date_MINUTES=minutes
+Iso8601Date_mm=mm
+Iso8601Date_MM=MM
+Iso8601Date_month=month
+Iso8601Date_MONTH_VALUE_MUST_BE_1_12=Month Value 
+Iso8601Date_MONTH_VALUE_NOT_2_DIGITS=Month Value 
+Iso8601Date_MONTH_VALUE_NOT_NUMERICAL=Month Value 
+Iso8601Date_MONTHS=months
+Iso8601Date_nn=nn
+Iso8601Date_NN=NN
+Iso8601Date_NO_SUCH_VALUE_PROVIDED=format '
+Iso8601Date_NO_VALUES_SET=No values have been set\r\n
+Iso8601Date_PLUS=+
+Iso8601Date_s=s
+Iso8601Date_second=second
+Iso8601Date_SECOND_VALUE_MUST_BE_0_AND_59=Second Value {0}: Second must be 0 and 59
+Iso8601Date_SECOND_VALUE_NOT_2_DIGITS_LONG=Second Value 
+Iso8601Date_SECOND_VALUE_NOT_NUMERICAL=Second Value 
+Iso8601Date_SECONDS=seconds
+Iso8601Date_ss=ss
+Iso8601Date_SS=SS
+Iso8601Date_sss=sss
+Iso8601Date_THE_DAY=the day 
+Iso8601Date_tt=tt
+Iso8601Date_tz_hour=timezone hour
+Iso8601Date_TZ_HOUR_VALUE_MUST_BE_0_OR_POSITIVE=Timezone Hour Value 
+Iso8601Date_TZ_HOUR_VALUE_MUST_BE_12_OR_LESS=Timezone Hour Value 
+Iso8601Date_TZ_HOUR_VALUE_MUST_BE_23_OR_LESS=Hour Value 
+Iso8601Date_TZ_HOURS=timezone hours
+Iso8601Date_TZ_MINUTE_VALUE_MUST_BE_0_OR_30=Timezone Minute Value 
+Iso8601Date_tz_minutes=timezone minutes
+Iso8601Date_TZ_MINUTES=timezone minutes
+Iso8601Date_TZ_NOT_DEFINED=Timezone required, but not defined
+Iso8601Date_TZ_PROHIBITED_BUT_DEFINED=Timezone prohibited, but is defined
+Iso8601Date_TZ_REQUIRED_BUT_NOT_DEFINED=Timezone required, but not defined
+Iso8601Date_U=U
+Iso8601Date_VALUE_INVALID=value for 
+Iso8601Date_VALUE_MISSING=value for 
+Iso8601Date_year=year
+Iso8601Date_YEAR_VALUE_NEGATIVE_NOT_SUPPORTED=Year Value 
+Iso8601Date_YEAR_VALUE_NOT_NUMERICAL=Year Value 
+Iso8601Date_YEARS=years
+Iso8601Date_yyyy=yyyy
+Iso8601Date_YYYY=YYYY
+Iso8601Date_ZERO=0
+NumberValidator_a_number=a number
+NumberValidator_an_Exponent=an exponent
+NumberValidator_an_Integer=an integer
+NumberValidator_decimal_portion=decimal portion
+NumberValidator_DOT=.
+NumberValidator_E=E
+NumberValidator_Exponent_Format_not_allowed_in_Context=exponent format is not allowed in this context
+NumberValidator_Exponent_Format_required_in_Context=exponent format is required in this context
+NumberValidator_INF=INF
+NumberValidator_minusINF=-INF
+NumberValidator_NaN=NaN
+NumberValidator_Number_empty=The number is empty
+NumberValidator_Only_Digits_after_Decimal_allowed_but_found=Only 
+NumberValidator_plusINF=+INF
+NumberValidator_Unexpected_Content_after_Parsing_Decimal=Unexpected content '
+NumberValidator_Unexpected_Content_after_Parsing_Exponent=Unexpected content '
+NumberValidator_Unexpected_Content_after_Parsing_Int=Unexpected content '
+NumberValidator_Unexpected_Content_at_Char_expecting_E=Unexpected content '
+NumberValidator_Unexpected_Content_expecting_Start_of=Unexpected content '
+NumberValidator_Unexpected_Content_following_in_Decimal=Unexpected content '
+NumberValidator_Unexpected_Content_NaN=Unexpected content '
+NumberValidator_Unexpected_End_of_Source=Unexpected end of source attempting to read '
+NumberValidator_Unexpected_End_of_Source_after_Sign_looking_for=Unexpected end of source after sign looking for 
+NumberValidator_Unexpected_End_of_Source_looking_for=Unexpected end of source looking for 
+NumberValidator_Value_Infinity=Value is infinity
+NumberValidator_Value_negative_Infinity=Value is negative infinity
+NumberValidator_Value_not_a_number=Value is not a number
+RomanNumberSpeller_0=Roman numbers cannot exceed 
+RomanNumberSpeller_10=X
+RomanNumberSpeller_11=IX
+RomanNumberSpeller_12=V
+RomanNumberSpeller_13=IV
+RomanNumberSpeller_14=I
+RomanNumberSpeller_2=M
+RomanNumberSpeller_3=CM
+RomanNumberSpeller_4=D
+RomanNumberSpeller_5=CD
+RomanNumberSpeller_6=C
+RomanNumberSpeller_7=XC
+RomanNumberSpeller_8=L
+RomanNumberSpeller_9=XL
+Speller_0=Minus 
+Speller_100=Eight
+Speller_102=Nine
+Speller_104=Ten
+Speller_106=Eleven
+Speller_108=Twelve
+Speller_110=Thirteen
+Speller_112=Fourteen
+Speller_114=Fifteen
+Speller_116=Sixteen
+Speller_118=Seventeen
+Speller_120=Eighteen
+Speller_122=Nineteen
+Speller_124=Twenty
+Speller_126=Thirty
+Speller_128=Forty
+Speller_130=Fifty
+Speller_132=Sixty
+Speller_134=Seventy
+Speller_136=Eighty
+Speller_138=Ninety
+Speller_140=Hundred
+Speller_142=Thousand
+Speller_144=Million
+Speller_146=Billion
+Speller_148=Trillion
+Speller_15=\ Thousand
+Speller_150=Quadrillion
+Speller_152=Quintillion
+Speller_154=and
+Speller_156=Minus
+Speller_158=,
+Speller_16=\ Million
+Speller_160=-
+Speller_165=[1-9]
+Speller_166=odig
+Speller_17=\ Billion
+Speller_18=\ Trillion
+Speller_19=\ Quadrillion
+Speller_20=\ Quintillion
+Speller_207=Invalid encoded text : 
+Speller_208=Undefined pattern variable name : 
+Speller_21=Zero
+Speller_22=One
+Speller_23=Two
+Speller_24=Three
+Speller_25=Four
+Speller_26=Five
+Speller_27=Six
+Speller_28=Seven
+Speller_29=Eight
+Speller_3=\ and 
+Speller_30=Nine
+Speller_31=Ten
+Speller_32=Eleven
+Speller_33=Twelve
+Speller_34=Thirteen
+Speller_35=Fourteen
+Speller_36=Fifteen
+Speller_37=Sixteen
+Speller_38=Seventeen
+Speller_39=Eighteen
+Speller_4=\\$
+Speller_40=Nineteen
+Speller_41=Twenty
+Speller_42=Thirty
+Speller_43=Forty
+Speller_44=Fifty
+Speller_45=Sixty
+Speller_46=Seventy
+Speller_47=Eighty
+Speller_48=Ninety
+Speller_49=-
+Speller_5=, 
+Speller_51=Expecting a number between 0 and 999: 
+Speller_52=\ Hundred
+Speller_55=\ and 
+Speller_58=Unknown or misplaced token : 
+Speller_59=quintillion
+Speller_60=quadrillion
+Speller_61=trillion
+Speller_62=billion
+Speller_63=million
+Speller_64=thousand
+Speller_65=minus
+Speller_66=minus
+Speller_68=Invalid starting token for text : 
+Speller_7=and 
+Speller_70=one
+Speller_72=zero 
+Speller_78=Unknonw token : 
+Speller_8=-
+Speller_80=Unknonw or invalid code character : 
+Speller_81=-
+Speller_82=-
+Speller_83=,
+Speller_84=Zero
+Speller_86=One
+Speller_88=Two
+Speller_9=,
+Speller_90=Three
+Speller_92=Four
+Speller_94=Five
+Speller_96=Six
+Speller_97=6
+Speller_98=Seven
+Speller_Crore=Crore
+Speller_Lakh=Lakh
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml.tests/.classpath b/bundles/org.eclipse.uomo.xml.tests/.classpath
new file mode 100644
index 0000000..cf36b56
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.xml.tests/.gitignore b/bundles/org.eclipse.uomo.xml.tests/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/bundles/org.eclipse.uomo.xml.tests/.project b/bundles/org.eclipse.uomo.xml.tests/.project
new file mode 100644
index 0000000..a02c8bb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.util.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.xml.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.xml.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..93d111b
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.xml.tests
+Bundle-SymbolicName: org.eclipse.uomo.xml.tests
+Bundle-Version: 0.6.0.qualifier
+Bundle-Vendor: Eclipse OSBP
+Fragment-Host: org.eclipse.uomo.util;bundle-version="0.6.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.uomo.xml.test
+Require-Bundle: org.junit;bundle-version="4.8.2",
+ org.eclipse.uomo.xml;bundle-version="0.6.0"
diff --git a/bundles/org.eclipse.uomo.xml.tests/build.properties b/bundles/org.eclipse.uomo.xml.tests/build.properties
new file mode 100644
index 0000000..ced5f40
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.uomo.xml.tests/pom.xml b/bundles/org.eclipse.uomo.xml.tests/pom.xml
new file mode 100644
index 0000000..4592e3a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo.bundles</artifactId>
+    	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>org.eclipse.uomo.xml.tests</artifactId>
+  <name>UOMo XML Tests</name>
+  <packaging>eclipse-test-plugin</packaging>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/DOMXMLWriterTests.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/DOMXMLWriterTests.java
new file mode 100644
index 0000000..4aea7e0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/DOMXMLWriterTests.java
@@ -0,0 +1,697 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2009, 2009, Copyright (c) 2009, 2009 Kestral Computing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.uomo.xml.impl.DOMXMLWriter;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+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;
+
+/**
+ * @author dennisn
+ *
+ */
+public class DOMXMLWriterTests {
+
+	private static DocumentBuilder docBuilder;
+	
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+		builderFactory.setNamespaceAware(true);
+		docBuilder = builderFactory.newDocumentBuilder();
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+	
+	private Document doc;
+	private DOMXMLWriter writer;
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		doc = docBuilder.newDocument();
+		writer = new DOMXMLWriter(doc);
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#DOMXMLWriter(org.w3c.dom.Document)}.
+	 */
+	@Test
+	public final void testDOMXMLWriterDocument() throws Exception {
+		assertEquals(doc, writer.getDOMDocument());
+	}
+
+//	/**
+//	 * Test method for {@link org.eclipse.ohf.utilities.xml.DOMXMLWriter#escapeXML(java.lang.String, boolean)}.
+//	 * Should move to XMLUtil testing
+//	 */
+//	@Test
+//	public final void testEscapeXML() {
+//		assertEquals("", DOMXMLWriter.escapeXML(null, false));
+//		assertEquals("abcdefg", DOMXMLWriter.escapeXML("abcdefg", false));
+//		assertEquals("&#39;ab&amp;&quot;&lt;&gt;~", DOMXMLWriter.escapeXML("\'ab&\"<>~", false));
+//		
+//		assertEquals("\n\r", DOMXMLWriter.escapeXML("\n\r", false));
+//		assertEquals("&#xA;", DOMXMLWriter.escapeXML("\n\r", true));
+//	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#abbreviationDefined(java.lang.String)}.
+	 */
+	@Test
+	public final void testAbbreviationDefined() throws Exception {
+		// test abbreviation defined in root
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		assertTrue(writer.abbreviationDefined("test"));
+		assertFalse(writer.abbreviationDefined("test_1"));
+		
+		// test abbreviation defined, but not yet commit to an element
+		writer.namespace("www.test2.com", "test2");
+		assertTrue(writer.abbreviationDefined("test"));
+		assertTrue(writer.abbreviationDefined("test2"));
+		assertFalse(writer.abbreviationDefined("test_1"));
+		writer.open("child1");
+		writer.close();
+		
+		// test abbreviation defined in another child
+		assertTrue(writer.abbreviationDefined("test"));
+		assertFalse(writer.abbreviationDefined("test2"));
+		assertFalse(writer.abbreviationDefined("test_1"));
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String, boolean)}.
+	 */
+	@Test
+	public final void testAttributeStringStringStringBoolean() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		
+		writer.attribute("", "test1", null, true);
+		writer.attribute("", "test2", "", true);
+		writer.attribute("", "test3", null, false);
+		writer.attribute("", "test4", "", false);
+		writer.attribute("", "test5", "value", true);
+		writer.open("child1");
+		Element node = writer.getCurrentElement();
+		writer.close();
+		assertFalse(node.hasAttribute("test1"));
+		assertFalse(node.hasAttribute("test2"));
+		assertTrue(node.hasAttribute("test3"));
+		assertEquals("", node.getAttribute("test3"));
+		assertTrue(node.hasAttribute("test4"));
+		assertEquals("", node.getAttribute("test4"));
+		assertTrue(node.hasAttribute("test5"));
+		assertEquals("value", node.getAttribute("test5"));
+		
+		writer.attribute("www.test.com", "test1", null, true);
+		writer.attribute("www.test.com", "test2", "", true);
+		writer.attribute("www.test.com", "test3", null, false);
+		writer.attribute("www.test.com", "test4", "", false);
+		writer.attribute("www.test.com", "test5", "value", true);
+		writer.open("child2");
+		node = writer.getCurrentElement();
+		writer.close();
+		assertFalse(node.hasAttribute("test:test1"));
+		assertFalse(node.hasAttribute("test:test2"));
+		assertTrue(node.hasAttribute("test:test3"));
+		assertEquals("", node.getAttribute("test:test3"));
+		assertTrue(node.hasAttribute("test:test4"));
+		assertEquals("", node.getAttribute("test:test4"));
+		assertTrue(node.hasAttribute("test:test5"));
+		assertEquals("value", node.getAttribute("test:test5"));
+
+		
+		try {
+			writer.attribute("www.error.com", "test1", "value", true);
+			fail("Should not able to create attribute with not yet defined-namespace");
+		} catch (Exception e) {
+		}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testAttributeStringStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		
+		writer.attribute("", "test1", null);
+		writer.attribute("", "test2", "");
+		writer.attribute("", "test3", "value");
+		writer.open("child1");
+		Element node = writer.getCurrentElement();
+		writer.close();
+		assertTrue(node.hasAttribute("test1"));
+		assertEquals("", node.getAttribute("test1"));
+		assertTrue(node.hasAttribute("test2"));
+		assertEquals("", node.getAttribute("test2"));
+		assertTrue(node.hasAttribute("test3"));
+		assertEquals("value", node.getAttribute("test3"));
+		
+		writer.attribute("www.test.com", "test1", null);
+		writer.attribute("www.test.com", "test2", "");
+		writer.attribute("www.test.com", "test3", "value");
+		writer.open("child2");
+		node = writer.getCurrentElement();
+		writer.close();
+		assertTrue(node.hasAttribute("test:test1"));
+		assertEquals("", node.getAttribute("test:test1"));
+		assertTrue(node.hasAttribute("test:test2"));
+		assertEquals("", node.getAttribute("test:test2"));
+		assertTrue(node.hasAttribute("test:test3"));
+		assertEquals("value", node.getAttribute("test:test3"));
+
+		
+		try {
+			writer.attribute("www.error.com", "test1", "value", true);
+			fail("Should not able to create attribute with not yet defined-namespace");
+		} catch (Exception e) {
+		}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#attribute(java.lang.String, java.lang.String, boolean)}.
+	 */
+	@Test
+	public final void testAttributeStringStringBoolean() throws Exception {
+		writer.open("root");
+		
+		writer.attribute("test1", null, true);
+		writer.attribute("test2", "", true);
+		writer.attribute("test3", null, false);
+		writer.attribute("test4", "", false);
+		writer.attribute("test5", "value", true);
+		writer.open("child1");
+		Element node = writer.getCurrentElement();
+		writer.close();
+		assertFalse(node.hasAttribute("test1"));
+		assertFalse(node.hasAttribute("test2"));
+		assertTrue(node.hasAttribute("test3"));
+		assertEquals("", node.getAttribute("test3"));
+		assertTrue(node.hasAttribute("test4"));
+		assertEquals("", node.getAttribute("test4"));
+		assertTrue(node.hasAttribute("test5"));
+		assertEquals("value", node.getAttribute("test5"));
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#attribute(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testAttributeStringString() throws Exception {
+		writer.open("root");
+		
+		writer.attribute("test3", null);
+		writer.attribute("test4", "");
+		writer.attribute("test5", "value", true);
+		writer.open("child1");
+		Element node = writer.getCurrentElement();
+		assertTrue(node.hasAttribute("test3"));
+		assertEquals("", node.getAttribute("test3"));
+		assertTrue(node.hasAttribute("test4"));
+		assertEquals("", node.getAttribute("test4"));
+		assertTrue(node.hasAttribute("test5"));
+		assertEquals("value", node.getAttribute("test5"));
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#attributeNoLines(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testAttributeNoLines() throws Exception {
+		writer.open("root");
+		
+		writer.attributeNoLines("test3", "value\n and more");
+		writer.open("child1");
+		Element node = writer.getCurrentElement();
+		assertEquals("value and more", node.getAttribute("test3"));
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#cData(java.lang.String)}.
+	 */
+	@Test
+	public final void testCData() throws Exception {
+		writer.open("root");
+		
+		writer.cData("test");
+		Node node = writer.getCurrentElement().getChildNodes().item(0);
+		assertTrue(node instanceof CDATASection);
+		assertEquals("test", node.getNodeValue());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#close(java.lang.String)}.
+	 */
+	@Test
+	public final void testCloseString() throws Exception {
+		writer.open("root");
+		
+		writer.open("test1");
+		writer.close("test1");
+		
+		try {
+			writer.close("not_root");
+			fail("'close()' should not success when name not matched current node name");
+		}
+		catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#close(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testCloseStringString() throws Exception {
+		writer.namespace("www.test.com");
+		writer.open("root");
+		
+		writer.open("www.test.com", "test1");
+		writer.close("www.test.com", "test1");
+		
+		try {
+			writer.close("www.test.com", "not_root");
+			fail("'close()' should not success when name not matched current node name");
+		}
+		catch (Exception e) {}
+		
+		try {
+			writer.close("www.error.com", "root");
+			fail("'close()' should not success when namespace not matched current node namespace");
+		}
+		catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#close()}.
+	 */
+	@Test
+	public final void testClose() throws Exception {
+		writer.namespace("www.test.com");
+		writer.open("root");
+		
+		writer.open("child");
+		Node child = writer.getCurrentElement();
+		assertEquals(doc.getDocumentElement(), child.getParentNode());
+		writer.close();
+		assertEquals(doc.getDocumentElement(), writer.getCurrentElement());
+		
+		writer.open("www.test.com", "child");
+		Node child2 = writer.getCurrentElement();
+		assertEquals(doc.getDocumentElement(), child2.getParentNode());
+		assertNotSame(child, child2);
+		writer.close();
+		assertEquals(doc.getDocumentElement(), writer.getCurrentElement());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#closeToLevel(int)}.
+	 */
+	@Test
+	public final void testCloseToLevel() throws Exception {
+		writer.namespace("www.test.com");
+		writer.open("root");
+		
+		writer.open("lvl2");
+		writer.open("www.test.com", "lvl3");
+		Element lvl3 = writer.getCurrentElement();
+		writer.open("lvl4");
+		writer.open("lvl5");
+		writer.open("lvl6");
+		
+		writer.closeToLevel(3);
+		assertEquals(lvl3, writer.getCurrentElement());
+		writer.closeToLevel(1);
+		assertEquals(doc.getDocumentElement(), writer.getCurrentElement());
+		writer.closeToLevel(0);
+		try {
+			writer.getCurrentElement();
+			fail("Should not able to access current element once close to level 0");
+		} catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#comment(java.lang.String, boolean)}.
+	 */
+	@Test
+	public final void testComment() throws Exception {
+		writer.namespace("www.test.com");
+		writer.open("root");
+		
+		writer.comment("some comment", true);
+		NodeList children = doc.getDocumentElement().getChildNodes();
+		boolean found = false;
+		for (int i = 0; !found && i < children.getLength(); i++) {
+			if (children.item(i) instanceof Comment
+					&& "some comment".equals(children.item(i).getNodeValue())) {
+				found = true;
+			}
+		}
+		assertTrue("Expected comment not found", found);
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, boolean)}.
+	 */
+	@Test
+	public final void testElementStringStringStringBoolean() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		Element root = doc.getDocumentElement();
+		
+		writer.element("www.test.com", "test1", null, true);
+		assertEquals(0, root.getChildNodes().getLength());
+		writer.element("www.test.com", "test2", "", true);
+		assertEquals(0, root.getChildNodes().getLength());
+		writer.element("www.test.com", "test3", null, false);
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test3").getLength());
+		writer.element("www.test.com", "test4", "", false);
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test4").getLength());
+		writer.element("www.test.com", "test5", "value", true);
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test5").getLength());
+		assertEquals("value", ((Element)root.getElementsByTagNameNS("www.test.com", "test5").item(0)).getTextContent());
+		
+		try {
+			writer.element("", "test5", "value", true);
+			fail("Shouldn't created element with unknown namespace");
+		} catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testElementStringStringStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		Element root = doc.getDocumentElement();
+		
+		writer.element("www.test.com", "test3", null, null);
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test3").getLength());
+		writer.element("www.test.com", "test4", "", "");
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test4").getLength());
+		
+		writer.element("www.test.com", "test5", "value", "comment");
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test5").getLength());
+		Element node = (Element)root.getElementsByTagNameNS("www.test.com", "test5").item(0);
+		assertEquals("value", node.getTextContent());
+		boolean found = false;
+		NodeList nodes = node.getChildNodes();
+		for (int i = 0; !found && i < nodes.getLength(); i++) {
+			if (nodes.item(i) instanceof Comment 
+					&& "comment".equals(nodes.item(i).getNodeValue())) {
+				found = true;
+			}
+		}
+		assertTrue("Comment has not created", found);
+		
+		try {
+			writer.element("", "test5", "value", "comment");
+			fail("Shouldn't created element with unknown namespace");
+		} catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#element(java.lang.String, java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testElementStringStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		Element root = doc.getDocumentElement();
+		
+		writer.element("www.test.com", "test3", null);
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test3").getLength());
+		writer.element("www.test.com", "test4", "");
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test4").getLength());
+		writer.element("www.test.com", "test5", "value");
+		assertEquals(1, root.getElementsByTagNameNS("www.test.com", "test5").getLength());
+		assertEquals("value", ((Element)root.getElementsByTagNameNS("www.test.com", "test5").item(0)).getTextContent());
+		
+		try {
+			writer.element("", "test5", "value");
+			fail("Shouldn't created element with unknown namespace");
+		} catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#element(java.lang.String, java.lang.String, boolean)}.
+	 */
+	@Test
+	public final void testElementStringStringBoolean() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		Element root = doc.getDocumentElement();
+		
+		writer.element("test1", null, true);
+		assertEquals(0, root.getChildNodes().getLength());
+		writer.element("test:test2", "", true);
+		assertEquals(0, root.getChildNodes().getLength());
+		writer.element("test3", null, false);
+		assertEquals(1, root.getElementsByTagName("test3").getLength());
+		writer.element("test:test4", "", false);
+		assertEquals(1, root.getElementsByTagName("test:test4").getLength());
+		writer.element("test5", "value", true);
+		assertEquals(1, root.getElementsByTagName("test5").getLength());
+		assertEquals("value", ((Element)root.getElementsByTagName("test5").item(0)).getTextContent());
+		
+		try {
+			writer.element("", "test5", "value", true);
+			fail("Shouldn't created element with unknown namespace");
+		} catch (Exception e) {}
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#element(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testElementStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		Element root = doc.getDocumentElement();
+		
+		writer.element("test1", "value");
+		assertEquals(1, root.getElementsByTagName("test1").getLength());
+		assertEquals("value", ((Element)root.getElementsByTagName("test1").item(0)).getTextContent());
+		
+		writer.element("test2", null);
+		assertEquals(1, root.getElementsByTagName("test2").getLength());
+//		assertNotNull((Element)root.getElementsByTagName("test2").item(0)).getTextContent()));
+		// FIXME
+		
+	}
+	
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#startCommentBlock()}.
+	 */
+	@Test
+	public final void testCommentBlock() throws Exception {
+		writer.open("root");
+		writer.startCommentBlock();
+		writer.attribute("attr1", "value1");
+		writer.attribute("attr2", "value2");
+		writer.element("node", "node-content");
+		writer.endCommentBlock();
+		
+		Node node = doc.getDocumentElement().getChildNodes().item(0);
+		assertTrue(node instanceof Comment);
+		assertEquals("<node attr1=\"value1\" attr2=\"value2\">node-content</node>", node.getNodeValue().trim());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#namespace(java.lang.String)}.
+	 */
+	@Test
+	public final void testNamespaceString() throws Exception {
+		String ns = "www.test.com";
+		writer.namespace(ns);
+		writer.open("root");
+		writer.open(ns, "child");
+		Element node = writer.getCurrentElement();
+		assertEquals(ns, node.getNamespaceURI());
+		NamedNodeMap attrs = doc.getDocumentElement().getAttributes();
+		boolean found = false;
+		for (int i = 0; !found && i < attrs.getLength(); i++) {
+			if (attrs.item(i).getNodeName().startsWith("xmlns")
+					&& ns.equals(attrs.item(i).getNodeValue()))
+				found = true;
+		}
+		assertTrue(found);
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#namespace(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testNamespaceStringString() throws Exception {
+		String ns = "www.test.com";
+		String prefix = "test";
+		writer.namespace(ns, prefix);
+		writer.open("root");
+		writer.open(ns, "child");
+		Element node = writer.getCurrentElement();
+		assertEquals(ns, node.getNamespaceURI());
+		assertEquals(prefix, node.getPrefix());
+		NamedNodeMap attrs = doc.getDocumentElement().getAttributes();
+		boolean found = false;
+		for (int i = 0; !found && i < attrs.getLength(); i++) {
+			if (attrs.item(i).getNodeName().equals("xmlns:" + prefix)
+					&& ns.equals(attrs.item(i).getNodeValue()))
+				found = true;
+		}
+		assertTrue(found);
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#namespaceDefined(java.lang.String)}.
+	 */
+	@Test
+	public final void testNamespaceDefined() throws Exception {
+		writer.namespace("www.test.com");
+		writer.namespace("www.test2.com", "test");
+		assertTrue(writer.namespaceDefined("www.test.com"));
+		assertTrue(writer.namespaceDefined("www.test2.com"));
+		assertFalse(writer.namespaceDefined("www.test3.com"));
+		writer.open("root");
+		writer.open("www.test.com", "child");
+		assertTrue(writer.namespaceDefined("www.test.com"));
+		assertTrue(writer.namespaceDefined("www.test2.com"));
+		assertFalse(writer.namespaceDefined("www.test3.com"));
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#open(java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testOpenStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		writer.open("www.test.com", "child");
+		assertEquals("test:child", writer.getCurrentElement().getNodeName());
+		assertEquals("www.test.com", writer.getCurrentElement().getNamespaceURI());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#open(java.lang.String, java.lang.String, java.lang.String)}.
+	 */
+	@Test
+	public final void testOpenStringStringString() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		writer.open("www.test.com", "child", "comment");
+		assertEquals("child", writer.getCurrentElement().getLocalName());
+		assertEquals("www.test.com", writer.getCurrentElement().getNamespaceURI());
+		boolean found = false;
+		NodeList nodes = writer.getCurrentElement().getChildNodes();
+		for (int i = 0; !found && i < nodes.getLength(); i++) {
+			if (nodes.item(i) instanceof Comment 
+					&& "comment".equals(nodes.item(i).getNodeValue()))
+				found = true;
+		}
+		assertTrue(found);
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#open(java.lang.String)}.
+	 */
+	@Test
+	public final void testOpenString() throws Exception {
+		writer.open("root");
+		assertEquals("root", writer.getCurrentElement().getNodeName());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#setDefaultNamespace(java.lang.String)}.
+	 */
+	@Test
+	public final void testSetDefaultNamespace() throws Exception {
+		writer.setDefaultNamespace("www.default.com");
+		assertEquals("www.default.com", writer.getDefaultNamespace());
+		writer.open("root");
+		assertEquals("www.default.com", doc.getDocumentElement().getNamespaceURI());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#setPretty(boolean)}.
+	 */
+	@Test
+	public final void testSetPretty() throws Exception {
+		writer.setPretty(true);
+		assertEquals(true, writer.isPretty());
+		
+		writer.setPretty(false);
+		assertEquals(false, writer.isPretty());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#text(java.lang.String)}.
+	 */
+	@Test
+	public final void testText() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		
+		writer.text("value");
+		assertEquals("value", doc.getDocumentElement().getTextContent());
+	}
+
+	/**
+	 * Test method for {@link org.eclipse.uomo.xml.impl.ohf.utilities.xml.DOMXMLWriter#writeBytes(byte[])}.
+	 */
+	@Test
+	public final void testWriteBytes() throws Exception {
+		writer.namespace("www.test.com", "test");
+		writer.open("root");
+		
+		writer.writeBytes("value".getBytes());
+		assertEquals("value", doc.getDocumentElement().getTextContent());
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLDateUtilTest.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLDateUtilTest.java
new file mode 100644
index 0000000..19545c8
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLDateUtilTest.java
@@ -0,0 +1,58 @@
+package org.eclipse.uomo.xml.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.eclipse.uomo.xml.XMLDateUtil;
+import org.junit.Test;
+
+@SuppressWarnings("deprecation")
+public class XMLDateUtilTest {
+
+    @Test
+    public final void testDate01() {
+	Date test = parse("2006-07-04T10:53:52");
+	assertEquals(2006, test.getYear() + 1900);
+	assertEquals(7, test.getMonth() + 1);
+	assertEquals(4, test.getDate());
+	assertEquals(10, test.getHours());
+	assertEquals(53, test.getMinutes());
+	assertEquals(52, test.getSeconds());
+    }
+
+    @Test
+    public final void testDate02() {
+	// Time zone offset is thrown away
+	Date test = parse("2006-07-04T10:53:52-03:00");
+	assertEquals(2006, test.getYear() + 1900);
+	assertEquals(7, test.getMonth() + 1);
+	assertEquals(4, test.getDate());
+	assertEquals(10, test.getHours());
+	assertEquals(53, test.getMinutes());
+	assertEquals(52, test.getSeconds());
+    }
+
+    @Test
+    public final void testInvalidDate() {
+	try {
+	    XMLDateUtil.parseXMLDate("3323--333-22");
+	} catch (ParseException e) {
+	    return;
+	}
+	fail("Expected parse exception");
+    }
+
+    private Date parse(String xmlDate) {
+	Date result = null;
+	try {
+	    result = XMLDateUtil.parseXMLDate(xmlDate);
+	} catch (ParseException e) {
+	    fail("Parse failed");
+	}
+	return result;
+    }
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLPullWriterTests.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLPullWriterTests.java
new file mode 100644
index 0000000..8511edc
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLPullWriterTests.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 Jiva Medical and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.xml.impl.XMLPullWriter;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+public class XMLPullWriterTests extends XMLTestCase {
+
+    @Test
+    @Ignore
+    public final void test1() throws UOMoException, XmlPullParserException,
+	    IOException, InterruptedException {
+	XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System
+		.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
+	factory.setNamespaceAware(true);
+	XmlPullParser xpp = factory.newPullParser();
+
+	xpp.setInput(new FileInputStream(new File(RESOURCE_PATH
+		+ "testPullWriterSource.xml")), null);
+
+	int eventType = xpp.next();
+	if (eventType != XmlPullParser.START_TAG)
+	    throw new XmlPullParserException("Unable to process XML document");
+
+	FileOutputStream stream = new FileOutputStream(new File(TEMP_FILENAME));
+	XMLPullWriter xwr = new XMLPullWriter(stream);
+	xwr.write(xpp, true, null, null);
+	stream.flush();
+	stream.close();
+
+	compareFiles(RESOURCE_PATH + "testPullWriterDest.xml", TEMP_FILENAME);
+    }
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestCase.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestCase.java
new file mode 100644
index 0000000..bff5267
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestCase.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 Jiva Medical and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.xml.impl.XMLReader;
+import org.eclipse.uomo.xml.impl.XMLWriter;
+import org.eclipse.uomo.xml.impl.XMLWriterParser;
+import org.junit.Before;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+public abstract class XMLTestCase implements
+	XMLTestConfiguration {
+
+    @Before
+    public void setUp() throws Exception {
+//	super.setUp();
+	checkOsxXmlHandlers();
+    }
+
+    public static void checkOsxXmlHandlers() {
+	// this is a workaround for a weird OSX related issue - something to do
+	// with the way Apple register Crimson.
+	// feel free to disable it if it's not a problem for you
+	if (isOsx()) {
+	    System
+		    .setProperty("javax.xml.parsers.DocumentBuilderFactory",
+			    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
+	    System
+		    .setProperty("javax.xml.parsers.SAXParserFactory",
+			    "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
+	    System
+		    .setProperty("org.w3c.dom.DOMImplementationSourceList",
+			    "com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");
+	}
+    }
+
+    private void prettyXML(String source, String dest) throws SAXException,
+	    IOException {
+	XMLWriter dst = new XMLWriter(new FileOutputStream(new File(dest)),
+		"UTF-8");
+	dst.setPretty(true);
+	dst.setSortAttributes(true);
+	XMLReader src = new XMLReader(new XMLWriterParser(dst));
+	src.parse(new FileInputStream(new File(source)));
+    }
+
+    private final static int CR = 13;
+    private final static int LF = 10;
+
+    protected void compareDOMs(String filename1, String filename2,
+	    String name1, String name2) throws FileNotFoundException,
+	    ParserConfigurationException, SAXException, IOException,
+	    InterruptedException, UOMoException {
+	Document one = loadDom(filename1);
+	Document two = loadDom(filename2);
+
+	String diff = compareElements(one.getDocumentElement(), two
+		.getDocumentElement(), "/");
+	if (diff != null) {
+	    showDiff(filename1, filename2, name1, name2, true, diff);
+	}
+    }
+
+    private String compareElements(Element e1, Element e2, String p) {
+	if (!e1.getNamespaceURI().equals(e2.getNamespaceURI()))
+	    return "element namespaces differ at " + p;
+	if (!e1.getLocalName().equals(e2.getLocalName()))
+	    return "element names differ at " + p;
+
+	String msg = compareAttributes(e1, e2, p);
+	if (msg != null)
+	    return msg;
+
+	p = p + "/" + e1.getNodeName();
+
+	int i = 0;
+	Node c1 = getNextRelevantNode(e1.getFirstChild());
+	Node c2 = getNextRelevantNode(e2.getFirstChild());
+	while (c1 != null && c2 != null) {
+	    if (c1.getNodeType() != c2.getNodeType())
+		return "Different node types ("
+			+ Integer.toString(c1.getNodeType()) + "/"
+			+ c2.getNodeType() + ") @ " + p;
+	    msg = null;
+	    if (c1.getNodeType() == Node.TEXT_NODE) {
+		msg = compareTexts((Text) c1, (Text) c2, p + "["
+			+ Integer.toString(i) + "]");
+	    } else if (c1.getNodeType() == Node.ELEMENT_NODE) {
+		msg = compareElements((Element) c1, (Element) c2, p + "["
+			+ Integer.toString(i) + "]");
+	    } else
+		msg = "unknown node type " + Integer.toString(c1.getNodeType());
+	    if (msg != null)
+		return msg;
+
+	    c1 = getNextRelevantNode(c1.getNextSibling());
+	    c2 = getNextRelevantNode(c2.getNextSibling());
+	    i++;
+	}
+	if (c1 != null && c2 == null)
+	    return "node present in one and not in two @ " + p;
+	if (c2 != null && c1 == null)
+	    return "node present in two and not in one @ " + p;
+	return null;
+    }
+
+    private String compareAttributes(Element e1, Element e2, String p) {
+	NamedNodeMap n1 = e1.getAttributes();
+	NamedNodeMap n2 = e2.getAttributes();
+
+	for (int i = 0; i < n1.getLength(); i++) {
+	    Node a1 = n1.item(0);
+	    Node a2 = n2
+		    .getNamedItemNS(a1.getNamespaceURI(), a1.getLocalName());
+	    if (a2 == null)
+		return "Unable to find attribute " + a1.getNodeName() + " @ "
+			+ p;
+	    if (a1.getNodeValue() != null || a2.getNodeValue() != null) {
+		if (a1.getNodeValue() == null || a2.getNodeValue() == null
+			|| !a1.getNodeValue().equals(a2.getNodeValue()))
+		    return "Attribute text differs @ " + p + "/@"
+			    + a1.getNodeName() + ": '" + a1.getNodeValue()
+			    + "' / '" + a2.getNodeValue() + "'";
+	    }
+	}
+
+	for (int i = 0; i < n2.getLength(); i++) {
+	    Node a2 = n2.item(0);
+	    Node a1 = n1
+		    .getNamedItemNS(a2.getNamespaceURI(), a2.getLocalName());
+	    if (a1 == null)
+		return "Unable to find attribute " + a2.getNodeName() + " @ "
+			+ p;
+	    if (a1.getNodeValue() != null || a2.getNodeValue() != null) {
+		if (a1.getNodeValue() == null || a2.getNodeValue() == null
+			|| !a1.getNodeValue().equals(a2.getNodeValue()))
+		    return "Attribute text differs @ " + p + "/@"
+			    + a1.getNodeName() + ": '" + a1.getNodeValue()
+			    + "' / '" + a2.getNodeValue() + "'";
+	    }
+	}
+
+	return null;
+    }
+
+    private String compareTexts(Text c1, Text c2, String p) {
+	String s1 = normaliseWhitespace(c1.getNodeValue());
+	String s2 = normaliseWhitespace(c2.getNodeValue());
+	if (s1 == null && s2 == null)
+	    return null;
+	else if (s1 == null || s2 == null || !s1.equals(s2))
+	    return "Text differs @ " + p + ": '" + s1 + "' / '" + s2 + "'";
+	else
+	    return null;
+    }
+
+    private String normaliseWhitespace(String s) {
+	StringBuilder bldr = new StringBuilder();
+	boolean w = false;
+	for (Character ch : s.toCharArray()) {
+	    if (!Character.isWhitespace(ch)) {
+		bldr.append(ch);
+		w = false;
+	    } else if (!w) {
+		bldr.append(' ');
+		w = true;
+	    } else {
+		// nothing
+	    }
+
+	}
+	return bldr.toString();
+    }
+
+    private Node getNextRelevantNode(Node node) {
+	while (node != null
+		&& node.getNodeType() != Node.ELEMENT_NODE
+		&& !(node.getNodeType() == Node.TEXT_NODE && !StringUtils
+			.isWhitespace(node.getNodeValue())))
+	    node = node.getNextSibling();
+	return node;
+    }
+
+    private Document loadDom(String filename)
+	    throws ParserConfigurationException, FileNotFoundException,
+	    SAXException, IOException {
+
+	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+	factory.setNamespaceAware(true);
+	DocumentBuilder builder = factory.newDocumentBuilder();
+	File file = new File(filename);
+	return builder.parse(new FileInputStream(file));
+
+    }
+
+    protected void compareXMLs(String filename1, String filename2,
+	    String name1, String name2, boolean makePretty) throws IOException,
+	    UOMoException, InterruptedException, SAXException {
+
+	FileInputStream one = new FileInputStream(new File(filename1));
+	FileInputStream two = new FileInputStream(new File(filename2));
+	int size1 = one.available();
+	int size2 = two.available();
+
+	boolean same = true;
+	int count = 0;
+	int ia1 = -1;
+	int ia2 = -1;
+
+	while (same && one.available() > 0 && two.available() > 0) {
+	    int i1 = ia1 != -1 ? ia1 : one.read();
+	    ia1 = -1;
+	    int i2 = ia2 != -1 ? ia2 : two.read();
+	    ia2 = -1;
+	    if (i1 == CR) {
+		i1 = LF;
+		ia1 = one.read();
+		if (ia1 == LF)
+		    ia1 = -1;
+	    }
+	    if (i2 == CR) {
+		i2 = LF;
+		ia2 = two.read();
+		if (ia2 == LF)
+		    ia2 = -1;
+	    }
+	    same = i1 == i2;
+	    count++;
+	}
+
+	int left1 = one.available();
+	int left2 = two.available();
+
+	one.close();
+	two.close();
+
+	if (!same || left1 > 0 || left2 > 0) {
+	    if (!same)
+		showDiff(filename1, filename2, name1, name2, makePretty,
+			"Content is not as expected @ "
+				+ Integer.toString(count) + " of "
+				+ Integer.toString(size1) + "/"
+				+ Integer.toString(size2));
+	    else
+		showDiff(filename1, filename2, name1, name2, makePretty,
+			"Content is same until end of file @ "
+				+ Integer.toString(size1) + "/"
+				+ Integer.toString(size2));
+	}
+
+    }
+
+    private void showDiff(String filename1, String filename2, String name1,
+	    String name2, boolean makePretty, String msg) throws SAXException,
+	    IOException, InterruptedException, UOMoException {
+	if (makePretty) {
+	    prettyXML(filename1, TEMP_PATH + name1 + ".xml");
+	    prettyXML(filename2, TEMP_PATH + name2 + ".xml");
+
+	} else {
+	    copyFile(filename1, TEMP_PATH + name1 + ".xml");
+	    copyFile(filename2, TEMP_PATH + name2 + ".xml");
+	}
+	if (!SKIP_THIRD_PARTY) {
+	    if (isOsx())
+		Runtime.getRuntime().exec(
+			COMPARE_PATH + " " + TEMP_PATH + name1 + ".xml" + " "
+				+ TEMP_PATH + name2 + ".xml");
+	    else
+		Runtime.getRuntime().exec(
+			COMPARE_PATH + " \"" + TEMP_PATH + name1 + ".xml"
+				+ "\" \"" + TEMP_PATH + name2 + ".xml" + "\"");
+	}
+	Thread.sleep(1000);
+	throw new UOMoException(msg);
+
+    }
+
+    private void copyFile(String source, String dest) throws SAXException,
+	    IOException {
+	InputStream in = new FileInputStream(new File(source));
+	OutputStream out = new FileOutputStream(new File(dest));
+
+	// Transfer bytes from in to out
+	byte[] buf = new byte[1024];
+	int len;
+	while ((len = in.read(buf)) > 0) {
+	    out.write(buf, 0, len);
+	}
+	in.close();
+	out.close();
+    }
+
+    protected void compareFiles(String filename1, String filename2)
+	    throws IOException, UOMoException, InterruptedException {
+	FileInputStream one = new FileInputStream(new File(filename1));
+	FileInputStream two = new FileInputStream(new File(filename2));
+	boolean same = one.available() == two.available();
+	while (same && one.available() > 0) {
+	    same = one.read() == two.read();
+	}
+
+	if (!same) {
+	    if (!SKIP_THIRD_PARTY)
+		Runtime.getRuntime().exec(
+			COMPARE_PATH + " \"" + filename1 + "\" \"" + filename2
+				+ "\"");
+	    Thread.sleep(1000);
+	    throw new UOMoException("Content is not as expected @ "
+		    + Integer.toString(one.available()));
+	}
+    }
+
+    protected void compareStrings(String content1, String content2)
+	    throws IOException, UOMoException, InterruptedException {
+	String filename1 = TEMP_FILENAME + "1";
+	String filename2 = TEMP_FILENAME + "2";
+	stringToFile(content1, filename1);
+	stringToFile(content2, filename2);
+	compareFiles(filename1, filename2);
+    }
+
+    private void stringToFile(String content, String filename)
+	    throws IOException {
+	FileWriter file = new FileWriter(new File(filename));
+	file.write(content);
+	file.flush();
+	file.close();
+    }
+
+    protected static boolean isOsx() {
+	String lcOSName = System.getProperty("os.name").toLowerCase();
+	boolean MAC_OS_X = lcOSName.startsWith("mac os x");
+	return MAC_OS_X;
+    }
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestConfiguration.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestConfiguration.java
new file mode 100644
index 0000000..019a211
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestConfiguration.java
@@ -0,0 +1,70 @@
+package org.eclipse.uomo.xml.test;
+
+/**
+ * note: in osx, you cannot have spaces in the name of the temporary directory
+ * 
+ * @author grahame
+ * 
+ */
+
+interface XMLTestConfiguration {
+
+    /**
+     * The starting location, often the path to the test suite/test file that is
+     * run by the launcher. (i.e. org.eclipse.ohf.h3et.tests when running the
+     * AllH3etTests)
+     */
+    public static final String STARTDIR = System.getenv("STARTDIR") != null ? System
+	    .getenv("STARTDIR")
+	    : "./";
+
+    // don't run third party programs
+    public final static boolean SKIP_THIRD_PARTY = System
+	    .getenv("SKIP_THIRD_PARTY") != null;
+
+    /**
+     * Third party programs
+     * 
+     * on Windows, we use Firefox and WinMerge
+     * 
+     * on OSX, we use Firefox and FileMerge (from XCode)
+     */
+
+    // root folder of third party programs
+    public final static String BIN_DIR_WIN = System.getenv("ProgramFiles") != null ? System
+	    .getenv("ProgramFiles")
+	    : "C:/Program Files";
+    public final static String BROWSER_PATH = System.getProperty("os.name")
+	    .toLowerCase().startsWith("mac os x") ? "open " : BIN_DIR_WIN
+	    + "/Mozilla FireFox/FireFox.exe";
+    public final static String COMPARE_PATH = System.getProperty("os.name")
+	    .toLowerCase().startsWith("mac os x") ? "/usr/bin/opendiff" : // consult
+									  // FileMerge.app
+									  // help
+									  // doco
+									  // (part
+									  // of
+									  // XCode)
+									  // +
+									  // remember
+									  // to
+									  // make
+									  // it
+									  // executable
+	    BIN_DIR_WIN + "/WinMerge/WinMerge.exe";
+
+    /**
+     * Temp dir for generating files
+     */
+    public static final String TEMP_PATH = System.getenv("TEMP") != null ? System
+	    .getenv("TEMP")
+	    : (System.getProperty("os.name").toLowerCase().startsWith(
+		    "mac os x") ? "/temp/" : "C:/temp/");
+
+    public static final String PLUGIN_ID = "org.eclipse.uomo.xml.tests";
+    public static final String RESOURCE_PATH = STARTDIR + "../" + PLUGIN_ID
+	    + "/src/";
+
+    public static final String TEMP_FILENAME = TEMP_PATH + "/res_tmp";
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestingTests.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestingTests.java
new file mode 100644
index 0000000..1910a8c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTestingTests.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 Jiva Medical and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.test;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class XMLTestingTests extends XMLTestCase {
+
+    public static final String SAMPLE_1 = "<root xmlns='test'><child name='c'/></root>";
+    public static final String SAMPLE_1_WS = "<root xmlns='test'> <child name='c'/> </root>";
+    public static final String SAMPLE_2 = "<root xmlns='test'><child name='d'/></root>";
+
+    @Test
+    public final void testOk() throws UOMoException, XmlPullParserException,
+	    IOException, InterruptedException, ParserConfigurationException,
+	    SAXException {
+	String f1 = TEMP_FILENAME + "1.test.xml";
+	StringToFile(SAMPLE_1, f1);
+	String f2 = TEMP_FILENAME + "2.test.xml";
+	StringToFile(SAMPLE_1, f2);
+	compareDOMs(f1, f2, "one", "two");
+    }
+
+    private void StringToFile(String source, String name) throws IOException {
+	File file = new File(name);
+	FileOutputStream out = new FileOutputStream(file);
+	OutputStreamWriter writer = new OutputStreamWriter(out);
+	writer.write(source);
+	writer.flush();
+
+    }
+
+    @Test
+    public final void testOkWS() throws UOMoException, XmlPullParserException,
+	    IOException, InterruptedException, ParserConfigurationException,
+	    SAXException {
+	String f1 = TEMP_FILENAME + "1.test.xml";
+	StringToFile(SAMPLE_1, f1);
+	String f2 = TEMP_FILENAME + "2.test.xml";
+	StringToFile(SAMPLE_1_WS, f2);
+	compareDOMs(f1, f2, "one", "two");
+    }
+
+    @Test
+    @Ignore
+    public final void testNotOkWS() throws UOMoException,
+	    XmlPullParserException, IOException, InterruptedException,
+	    ParserConfigurationException, SAXException {
+	String f1 = TEMP_FILENAME + "1.test.xml";
+	StringToFile(SAMPLE_1, f1);
+	String f2 = TEMP_FILENAME + "2.test.xml";
+	StringToFile(SAMPLE_2, f2);
+	try {
+	    compareDOMs(f1, f2, "one", "two");
+	    fail();
+	} catch (UOMoException e) {
+	    // empty catch
+	}
+    }
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTests.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTests.java
new file mode 100644
index 0000000..1101ce2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLTests.java
@@ -0,0 +1,25 @@
+package org.eclipse.uomo.xml.test;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	XMLDateUtilTest.class,
+	XMLPullWriterTests.class,
+	XMLWriterTest.class,
+	XMLTestingTests.class
+})
+public class XMLTests {
+
+	/**
+	 * For use with JUnit3 runner
+	 * @deprecated
+	 */
+	public static Test suite() {
+		return new JUnit4TestAdapter(XMLTests.class);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLWriterTest.java b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLWriterTest.java
new file mode 100644
index 0000000..6099f51
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/org/eclipse/uomo/xml/test/XMLWriterTest.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 Jiva Medical and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.eclipse.uomo.xml.impl.XMLWriter;
+import org.junit.Test;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class XMLWriterTest extends XMLTestCase {
+
+    @Test
+    public final void testPlain() throws UOMoException, XmlPullParserException,
+	    IOException, InterruptedException {
+	ByteArrayOutputStream stream = new ByteArrayOutputStream();
+	XMLWriter xml = new XMLWriter(stream, "UTF-8");
+	xml.setPretty(false);
+	xml.start();
+	xml.namespace("urn:testuri.org", "ns");
+	xml.open("urn:testuri.org", "n1");
+	xml.open("urn:testuri.org", "n2");
+	xml.text("test");
+	xml.close();
+	xml.open("urn:testuri.org", "n2");
+	xml.text("test\n");
+	xml.close();
+	xml.close();
+	xml.close();
+	String output = stream.toString();
+	String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+		+ "<ns:n1 xmlns:ns=\"urn:testuri.org\">"
+		+ "<ns:n2>test</ns:n2>" + "<ns:n2>test\n</ns:n2>" + "</ns:n1>";
+	assertTrue(output.equals(expected));
+    }
+
+    @Test
+    public final void testPretty() throws UOMoException, XmlPullParserException,
+	    IOException, InterruptedException {
+	ByteArrayOutputStream stream = new ByteArrayOutputStream();
+	XMLWriter xml = new XMLWriter(stream, "UTF-8");
+	xml.setPretty(true);
+	xml.start();
+	xml.namespace("urn:testuri.org", "ns");
+	xml.open("urn:testuri.org", "n1");
+	xml.open("urn:testuri.org", "n2");
+	xml.text("test");
+	xml.close();
+	xml.open("urn:testuri.org", "n2");
+	xml.text("test\n");
+	xml.close();
+	xml.close();
+	xml.close();
+	String output = stream.toString();
+	String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n"
+		+ "<ns:n1 xmlns:ns=\"urn:testuri.org\">\n"
+		+ "  <ns:n2>test</ns:n2>\n" + "  <ns:n2>test\n</ns:n2>\n"
+		+ "</ns:n1>";
+	System.out.println("\r\noutput");
+	System.out.print("--" + output + "--");
+	System.out.println("\r\nexpected");
+	System.out.print("--" + expected + "--");
+	assertTrue(output.equals(expected));
+    }
+
+}
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterDest.xml b/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterDest.xml
new file mode 100644
index 0000000..db389c2
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterDest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<name1 xmlns="urn:test" attr1="value1" xmlns:ns0="urn:test2" ns0:attr2="value2">
+  <name2>
+    <p>This is some text with an <ns0:name3>extension</ns0:name3></p>
+    <p>this word is <b>bold</b>.</p>
+  </name2>
+</name1>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterSource.xml b/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterSource.xml
new file mode 100644
index 0000000..1d511cb
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml.tests/src/testPullWriterSource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<name1 xmlns="urn:test" xmlns:ns="urn:test2" attr1="value1" ns:attr2="value2">
+  <name2>
+    <p>This is some text with an <ns:name3>extension</ns:name3></p>
+    <p>this word is <b>bold</b>.</p>
+  </name2>
+</name1>
diff --git a/bundles/org.eclipse.uomo.xml/.classpath b/bundles/org.eclipse.uomo.xml/.classpath
new file mode 100644
index 0000000..87466f7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry exported="true" kind="lib" path="libs/xmlpull_1_1_3_4b.jar"/>
+	<classpathentry exported="true" kind="lib" path="libs/xpp3_min-1.1.3.4.O.jar"/>
+	<classpathentry kind="src" path="src/main/java/"/>
+	<classpathentry kind="src" path="src/main/resources/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/bundles/org.eclipse.uomo.xml/.gitignore b/bundles/org.eclipse.uomo.xml/.gitignore
new file mode 100644
index 0000000..e7da900
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/.gitignore
@@ -0,0 +1,3 @@
+/target
+/.settings
+/target
diff --git a/bundles/org.eclipse.uomo.xml/.project b/bundles/org.eclipse.uomo.xml/.project
new file mode 100644
index 0000000..f2e259d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/.project
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.xml</name>
+	<comment>UOMo adds Units of Measurement support for IT Systems and Services both to Language and Data. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+	<projects>
+		<project>org.eclipse.uomo.core</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.uomo.xml/.springBeans b/bundles/org.eclipse.uomo.xml/.springBeans
new file mode 100644
index 0000000..6c6cb5a
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.5.0.201010221000-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/bundles/org.eclipse.uomo.xml/META-INF/MANIFEST.MF b/bundles/org.eclipse.uomo.xml/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..f1d7fbf
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.uomo.xml
+Bundle-SymbolicName: org.eclipse.uomo.xml
+Bundle-Version: 0.6.0.qualifier
+Require-Bundle: org.eclipse.uomo.core;bundle-version="0.6.0",
+ org.apache.commons.lang;bundle-version="2.6.0",
+ org.apache.xerces,
+ org.junit;bundle-version="4.8.2"
+Bundle-Vendor: Eclipse OSBP
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ClassPath: libs/xmlpull_1_1_3_4b.jar,
+ libs/xpp3_min-1.1.3.4.O.jar,.
+Export-Package: org.eclipse.uomo.xml,
+ org.eclipse.uomo.xml.impl;
+  uses:="org.apache.xerces.parsers,
+   org.xmlpull.v1,
+   org.apache.xerces.xni,
+   org.eclipse.uomo.xml,
+   org.xml.sax.helpers,
+   org.w3c.dom,
+   org.xml.sax",
+ org.xmlpull.mxp1,
+ org.xmlpull.v1
+Import-Package: org.eclipse.osgi.util;version="1.1.0"
diff --git a/bundles/org.eclipse.uomo.xml/build.properties b/bundles/org.eclipse.uomo.xml/build.properties
new file mode 100644
index 0000000..873c894
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/build.properties
@@ -0,0 +1,5 @@
+source.. = src/main/java/,src/main/resources/
+output.. = target/classes
+bin.includes = META-INF/,\
+               .,\
+               libs/xmlpull_1_1_3_4b.jar
diff --git a/bundles/org.eclipse.uomo.xml/libs/xmlpull_1_1_3_4b.jar b/bundles/org.eclipse.uomo.xml/libs/xmlpull_1_1_3_4b.jar
new file mode 100644
index 0000000..a63832c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/libs/xmlpull_1_1_3_4b.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.xml/libs/xpp3_min-1.1.3.4.O.jar b/bundles/org.eclipse.uomo.xml/libs/xpp3_min-1.1.3.4.O.jar
new file mode 100644
index 0000000..640441d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/libs/xpp3_min-1.1.3.4.O.jar
Binary files differ
diff --git a/bundles/org.eclipse.uomo.xml/pom.xml b/bundles/org.eclipse.uomo.xml/pom.xml
new file mode 100644
index 0000000..be48860
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/pom.xml
@@ -0,0 +1,47 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>org.eclipse.uomo.bundles</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.xml</artifactId>
+	<name>UOMo XML</name>
+	<packaging>eclipse-plugin</packaging>
+
+	<!-- ======================================================= -->
+	<!-- Build Settings -->
+	<!-- ======================================================= -->
+	<build>
+		<plugins>
+			<!-- ======================================================= -->
+			<!-- Compilation -->
+			<!-- ======================================================= -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>${project.build.javaVersion}</source>
+					<target>${project.build.javaVersion}</target>
+					<encoding>${project.build.sourceEncoding}</encoding>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.6</version>
+		</dependency>
+		<dependency>
+			<artifactId>xpp3_min</artifactId>
+            <groupId>xpp3</groupId>
+			<version>1.1.3.4.O</version>
+		</dependency>
+	</dependencies>
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/DOMUtil.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/DOMUtil.java
new file mode 100644
index 0000000..c5f7f08
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/DOMUtil.java
@@ -0,0 +1,407 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *    B2 International - added generateXMLString(DocumentFragment, boolean)
+ *******************************************************************************/
+package org.eclipse.uomo.xml;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * XML utility class.
+ * 
+ * @author Grahame Grieve
+ * @author Zsolt Torok
+ */
+public final class DOMUtil {
+
+	//XML Settings
+	private static final String XML_VERSION = "1.0";
+    private static final String XML_ENCODING = "UTF-8";
+
+    private DOMUtil() {}
+    
+	public static int getIndex(Node parentNode, Node child) {
+		NodeList nodeList = parentNode.getChildNodes();
+		int index = -1;
+		int size = nodeList.getLength();
+		for (int i = 0; i < size; i++) {
+			if (nodeList.item(i) == child) {
+				index = i;
+				break;
+			}
+		}
+		return index;
+	}
+	
+	public static boolean isCommentAllowed(Node node) {
+		
+		short type=node.getNodeType();
+		return type==Node.ELEMENT_NODE || type==Node.TEXT_NODE;
+	}
+	
+	/**
+	 * Generates a string representation of an XML document
+	 * @param DOM document
+	 * @return XML document in a string
+	 * @throws IOException
+	 */
+	public static synchronized String generateXMLString(Document doc) throws IOException {
+		StringWriter  stringWriter    = null;
+	    XMLSerializer serializer   = null;
+	    OutputFormat  outputFormat    = null;
+	    String result= null;
+
+	    serializer = new XMLSerializer();
+	    stringWriter = new StringWriter();
+	    outputFormat = new OutputFormat();
+
+	    // Setup format settings
+	    outputFormat.setEncoding(XML_ENCODING);
+	    outputFormat.setVersion(XML_VERSION);
+	    outputFormat.setIndenting(true);
+	    outputFormat.setIndent(4);
+	    serializer.setOutputCharStream(stringWriter);
+	    serializer.setOutputFormat(outputFormat);
+	    serializer.serialize(doc);
+	    result = stringWriter.toString();
+	    stringWriter.close();	   
+	    return result;
+	}
+	
+	public static synchronized String generateXMLString(DocumentFragment fragment, boolean omitXMLDeclaration) throws IOException {
+		if (omitXMLDeclaration) {
+			StringWriter  stringWriter    = null;
+		    XMLSerializer serializer   = null;
+		    OutputFormat  outputFormat    = null;
+		    String result= null;
+
+		    serializer = new XMLSerializer();
+		    stringWriter = new StringWriter();
+		    outputFormat = new OutputFormat();
+
+		    outputFormat.setOmitXMLDeclaration(true);
+		    outputFormat.setIndenting(true);
+		    outputFormat.setIndent(4);
+		    serializer.setOutputCharStream(stringWriter);
+		    serializer.setOutputFormat(outputFormat);
+		    serializer.serialize(fragment);
+		    result = stringWriter.toString();
+		    stringWriter.close();	   
+		    return result;
+			
+		} else
+			generateXMLString(fragment);
+		return null;
+	}
+	
+	/**
+	 * Generates a string representation of a document fragment.
+	 * @param fragment to convert to XML
+	 * @return String XML
+	 * @throws IOException
+	 */
+	public static synchronized String generateXMLString(DocumentFragment fragment) throws IOException {
+		StringWriter  stringWriter    = null;
+	    XMLSerializer serializer   = null;
+	    OutputFormat  outputFormat    = null;
+	    String result= null;
+
+	    serializer = new XMLSerializer();
+	    stringWriter = new StringWriter();
+	    outputFormat = new OutputFormat();
+
+	    // Setup format settings
+	    outputFormat.setEncoding(XML_ENCODING);
+	    outputFormat.setVersion(XML_VERSION);
+	    outputFormat.setIndenting(true);
+	    outputFormat.setIndent(4);
+	    serializer.setOutputCharStream(stringWriter);
+	    serializer.setOutputFormat(outputFormat);
+	    serializer.serialize(fragment);
+	    result = stringWriter.toString();
+	    stringWriter.close();	   
+	    return result;
+	}
+	
+	/**
+	 * Generates a string representation of the XML element
+	 * passed in.
+	 * @param element to convert an XML string
+	 * @return string XML
+	 * @throws IOException
+	 */
+	public static synchronized String generateXMLString(Element element) throws IOException{
+
+	    StringWriter  stringWriter    = null;
+	    XMLSerializer serializer   = null;
+	    OutputFormat  outputFormat    = null;
+	    String result= null;
+
+	    serializer = new XMLSerializer();
+	    stringWriter = new StringWriter();
+	    outputFormat = new OutputFormat();
+
+	    // Setup format settings
+	    outputFormat.setEncoding(XML_ENCODING);
+	    outputFormat.setVersion(XML_VERSION);
+	    outputFormat.setIndenting(true);
+	    outputFormat.setIndent(4);
+	    outputFormat.setOmitXMLDeclaration(true);
+	    serializer.setOutputCharStream(stringWriter);
+	    serializer.setOutputFormat(outputFormat);
+	    serializer.serialize(element);
+	    result = stringWriter.toString();
+	    stringWriter.close();	   
+	    return result;
+	  }
+	
+	/**
+	 * Use the basePrefix to define new name-space prefix
+	 * If the basePrefix is already used for other name-space, a number will be added to the prefix to create
+	 * a new unique prefix
+	 * 
+	 * @param parent
+	 * @param namespace
+	 * @param basePrefix
+	 * @return the prefix that is now associated with this name-space.
+	 */
+	public static String addNamespacePrefix(Element parent, String namespace, String basePrefix) {
+		String result = suggestNamespacePrefix(parent, namespace, basePrefix);
+		
+		parent.getOwnerDocument().getDocumentElement().setAttribute("xmlns:" + result, namespace);
+		return result;
+	}
+
+	/**
+	 * To find unallocated name-space prefix that can be used to define given name-space.
+	 * This method often call with addNamespacePrefix;
+	 * 
+	 * @param parent
+	 * @param namespace
+	 * @param basePrefix
+	 * @return
+	 */
+	public static String suggestNamespacePrefix(Element parent, String namespace, String basePrefix) {
+		String result = basePrefix;
+		if (result == null) result = "ns";
+		int count = 0;
+		String foundNS = lookupPrefixOnElement(parent, basePrefix);
+		while (foundNS != null && !foundNS.equals(namespace)) {
+			count++;
+			result = basePrefix + count;
+		}
+		return result;
+	}
+
+	/**
+	 * Moved from DefnANY
+	 * Identified all prefix defined unto (and include) this element
+	 * 
+	 * @param element
+	 * @param namespace
+	 * @return null if this name-space is not declared, or the defined-prefix used for this name-space
+	 * 
+	 * @see
+	 *	org.eclipse.ohf.h3et.instanceeditor.core.util.DOMUtility#lookupPrefixForNamespace(org.w3c.dom.Element, org.w3c.dom.Element, java.lang.String)
+	 */
+	public static String lookupPrefixForNamespace(Element element, String namespace) {
+		String result = lookupNamespaceOnElement(element, namespace);
+		if (result == null) {
+			if (element.getParentNode() != null && element.getParentNode() instanceof Element)
+				result = lookupPrefixForNamespace((Element) element.getParentNode(), namespace);
+			else if (element.getOwnerDocument() != null && element.getOwnerDocument().getDocumentElement() != null
+					&& element.getOwnerDocument().getDocumentElement() != element)
+				/*
+				 * if element is not yet hooked up to its parent, then parent is null
+				 * so we must try to find prefix in root
+				 * Note that this is not entirely correct, as other prefix may be defined enroute to its parent
+				 */
+				result = lookupPrefixForNamespace(element.getOwnerDocument().getDocumentElement(), namespace);
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * In case the element is not yet appended into the XML tree, the prospective parent
+	 * need to be supplied to correctly find all the defined prefix in context
+	 *
+	 * @param parent the element parent-to-be (in case the element is not yet add to the XML structure)
+	 * @param element
+	 * @param namespace
+	 * @return null if this name-space is not declared, 
+	 * or the defined-prefix used for this name-space
+	 */
+	public static String lookupPrefixForNamespace(Element parent, Element element, String namespace) {
+		String result = lookupNamespaceOnElement(element, namespace);
+		if (result == null) {
+			if (element.getParentNode() != null && element.getParentNode() instanceof Element)
+				result = lookupPrefixForNamespace((Element) element.getParentNode(), namespace);
+			else if (parent != null)
+				result = lookupPrefixForNamespace(parent, namespace);
+			else if (element.getOwnerDocument() != null && element.getOwnerDocument().getDocumentElement() != null)
+				/*
+				 * if element is not yet hooked up to its parent, then parent is null
+				 * so we must try to find prefix in root
+				 * Note that this is not entirely correct, as other prefix may be defined enroute to its parent
+				 */
+				result = lookupPrefixForNamespace(element.getOwnerDocument().getDocumentElement(), namespace);
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * @param element
+	 * @param namespace
+	 * @return
+	 */
+	private static String lookupNamespaceOnElement(Element element, String namespace) {
+		
+		for (int i = 0; i < element.getAttributes().getLength(); i++) {
+			Attr attr = (Attr) element.getAttributes().item(i);
+			String name = attr.getNodeName();
+					
+			if (name.startsWith("xmlns") && namespace.equals(attr.getNodeValue())) {
+				if (name.equals("xmlns")) 
+					return "";
+				else 
+					return name.substring(6);				
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * @param element
+	 * @param prefix
+	 * @return the name-space corresponding to this prefix, or null
+	 */
+	public static String lookupNamespaceForPrefix(Element element, String prefix) {
+		String result = lookupPrefixOnElement(element, prefix);
+		if (result == null && element.getParentNode() != null && element.getParentNode() instanceof Element) {
+			result = lookupNamespaceForPrefix((Element) element.getParentNode(), prefix);
+		}
+		return result;
+	}
+
+	
+	/**
+	 * @param element
+	 * @param prefix
+	 * @return the name-space corresponding to this prefix, or null
+	 */
+	public static String lookupPrefixOnElement(Element element, String prefix) {
+
+		for (int i = 0; i < element.getAttributes().getLength(); i++) {
+			Attr attr = (Attr) element.getAttributes().item(i);
+			String name = attr.getNodeName();
+
+			if (name.startsWith("xmlns:") && name.endsWith(":"+prefix)) {
+				return attr.getNodeValue();
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Sometimes, the element is created in DOM 1 so prefix is prepend directly into node name.
+	 * This method handle both case of prefix, and fall back to the name-space assigned at creation
+	 * @param node
+	 * @return the name-space of this element (can be null if using DOM 1 with default name-space)
+	 */
+	public static String lookupNamespaceForElement(Element node) {
+		if (node.getPrefix() != null)
+			return lookupNamespaceForPrefix(node, node.getPrefix());
+		else if (node.getNodeName().indexOf(":") > 0)
+			return lookupNamespaceForPrefix(node, node.getNodeName().substring(0, node.getNodeName().indexOf(":")));
+		return node.getNamespaceURI();
+	}
+	
+	/**
+	 * If node is element, then return its own name-space.
+	 * If node is an attribute, then return the name-space of its owner element
+	 * Otherwise, return null.
+	 * @param node
+	 * @return name-space
+	 */
+	public static String lookupNamespaceForNode(Node node) {
+		if (node instanceof Attr) {
+			String name = node.getNodeName();
+			if (name.indexOf(":") > 0)
+				return lookupNamespaceForPrefix(((Attr)node).getOwnerElement(), name.substring(0, name.indexOf(":")));
+			else
+				return lookupNamespaceForElement(((Attr)node).getOwnerElement());
+		}
+		else if (node instanceof Element)
+			return lookupNamespaceForElement((Element) node);
+		else
+			return null;
+	}
+
+	public static boolean hasContent(Element element) {
+		Node node = element.getFirstChild();
+		while (node != null) {
+			if (node.getNodeType() == Node.ELEMENT_NODE || node.getNodeType() == Node.TEXT_NODE || 
+					node.getNodeType() == Node.ENTITY_NODE || node.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
+					node.getNodeType() == Node.CDATA_SECTION_NODE)
+				return true;
+			node = node.getNextSibling();
+		}
+		return false;
+	}
+
+	public static String getNodeLocalName(Node node) {
+		String result = node.getLocalName();
+		if (result == null)
+			result = node.getNodeName();
+		return result;
+	}
+
+	public static Element getFirstElement(Element element) {
+		Node node = element.getFirstChild();
+		while (node != null && !(node instanceof Element))
+			node = node.getNextSibling();
+		return (Element) node;
+	}
+
+	public static Element getNextElement(Element element) {
+		Node node = element.getNextSibling();
+		while (node != null && !(node instanceof Element))
+			node = node.getNextSibling();
+		return (Element) node;
+	}
+
+	public static Element getFirstElementByName(Element element, String name) {
+		Node node = element.getFirstChild();
+		while (node != null && (!(node instanceof Element) || !node.getLocalName().equals(name)))
+			node = node.getNextSibling();
+		return (Element) node;
+	}
+
+	public static Element getNextElementByName(Element element, String name) {
+		Node node = element.getNextSibling();
+		while (node != null && (!(node instanceof Element) || !node.getLocalName().equals(name)))
+			node = node.getNextSibling();
+		return (Element) node;
+	}
+
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/IXMLWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/IXMLWriter.java
new file mode 100644
index 0000000..02e4246
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/IXMLWriter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2009, Copyright (c) 2009, 2009 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml;
+
+import java.io.IOException;
+
+/**
+ * Generalize 
+ * @author dennisn
+ */
+public interface IXMLWriter {
+	
+	public abstract void start() throws IOException;
+
+	public abstract void attribute(String namespace, String name, String value,
+			boolean onlyIfNotEmpty) throws IOException;
+
+	public abstract void attribute(String namespace, String name, String value)
+			throws IOException;
+
+	public abstract void attribute(String name, String value,
+			boolean onlyIfNotEmpty) throws IOException;
+
+	public abstract void attribute(String name, String value)
+			throws IOException;
+
+	public abstract void attributeNoLines(String name, String value)
+			throws IOException;
+
+//	public abstract XMLNamespace findByNamespace(String namespace);
+
+	public abstract boolean namespaceDefined(String namespace);
+
+//	public abstract XMLNamespace findByAbbreviation(String abbreviation);
+
+	public abstract boolean abbreviationDefined(String abbreviation);
+
+//	public abstract XMLNamespace findDefaultNamespace();
+
+	public abstract String getDefaultNamespace();
+
+	public abstract void namespace(String namespace) throws IOException;
+
+	public abstract void setDefaultNamespace(String namespace) throws IOException;
+
+	public abstract void namespace(String namespace, String abbreviation)
+			throws IOException;
+
+	public abstract void comment(String comment, boolean doPretty)
+			throws IOException;
+
+	public abstract void open(String namespace, String name) throws IOException;
+
+	public abstract void open(String namespace, String name, String comment)
+			throws IOException;
+
+	public abstract void close(String name) throws IOException;
+
+	public abstract void close(String namespace, String name)
+			throws IOException;
+
+	public abstract void closeToLevel(int count) throws IOException;
+
+	public abstract void close() throws IOException;
+
+	public abstract void open(String name) throws IOException;
+
+	public abstract void element(String namespace, String name, String content,
+			boolean onlyIfNotEmpty) throws IOException;
+
+	public abstract void element(String namespace, String name, String content,
+			String comment) throws IOException;
+
+	public abstract void element(String namespace, String name, String content)
+			throws IOException;
+
+	public abstract void element(String name, String content,
+			boolean onlyIfNotEmpty) throws IOException;
+
+	public abstract void element(String name, String content)
+			throws IOException;
+
+	public abstract void text(String content) throws IOException;
+	
+	public abstract void text(String content, boolean dontEscape) throws IOException;
+
+	public abstract void cData(String text) throws IOException;
+
+	public abstract void writeBytes(byte[] bytes) throws IOException;
+
+	public abstract boolean isPretty() throws IOException;
+
+	public abstract void setPretty(boolean pretty) throws IOException;
+
+	/**
+	 * Start comment inserts a <!-- in the stream, but allows the user to 
+	 * go on creating xml content as usual, with proper formatting applied etc.
+	 * Any comments inserted inside a comment will be terminated with -- > instead of -->
+	 * so the comment doesn't close prematurely.
+	 * @throws IOException 
+	 */
+	public abstract void startCommentBlock() throws IOException;
+
+	public abstract void endCommentBlock() throws IOException;
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLDateUtil.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLDateUtil.java
new file mode 100644
index 0000000..96284a7
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLDateUtil.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2010, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * @author Grahame Grieve
+ * @author Werner Keil
+ *
+ * TODO add method to return UOM TimeUnit, too
+ */
+public final class XMLDateUtil {
+	
+	/** Utility class, don't instanciate */
+	private XMLDateUtil() {}
+	
+	/** 
+	 * Returns a java.util.Date for a given xml xs:dateTime, ignoring the timezone. Needs to be
+	 * updated to include the numerous xs:dateTime year, timezone, etc. specifications.
+	 * 
+	 * @param xmlDate Date string formatted as xs:dateTime
+	 * @return java.util.Date for given xmlDate
+	 * @throws ParseException
+	 */
+	public static Date parseXMLDate(String xmlDate) throws ParseException {
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+		return formatter.parse(xmlDate);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLMessages.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLMessages.java
new file mode 100644
index 0000000..c58f2fd
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLMessages.java
@@ -0,0 +1,15 @@
+package org.eclipse.uomo.xml;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class XMLMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.uomo.xml.messages"; //$NON-NLS-1$
+	public static String XMLObjectParsers_stackUnderflow;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, XMLMessages.class);
+	}
+
+	private XMLMessages() {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLObjectParser.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLObjectParser.java
new file mode 100644
index 0000000..e92567d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLObjectParser.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public abstract class XMLObjectParser {
+
+	private int useCount = 0;
+	private String namespace;
+	private String name;
+	private String path;
+	private boolean root;
+	
+	public boolean isRoot() {
+		return root;
+	}
+
+	public void setRoot(boolean root) {
+		this.root = root;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getNamespace() {
+		return namespace;
+	}
+
+	public void setNamespace(String namespace) {
+		this.namespace = namespace;
+	}
+
+	public void use() {
+		useCount++;
+	}
+	
+	public boolean unUse() {
+		useCount--;
+		return useCount == 0; 
+	}
+	
+	public void start(String namespace, String name, String defaultNamespace, Attributes attributes) throws SAXException {
+	}
+	
+	public void end() throws SAXException {
+		
+	}
+	
+	public boolean hasText() throws SAXException {
+		return false;
+	}
+	
+	public void findText(char[] ch, int start, int length, boolean whitespace) throws SAXException {
+		if (!whitespace && !hasText())
+			throw new SAXException("Unexpected Text Content \""+new String(ch, start, length)+"\" at "+path);
+	}
+	
+	public XMLObjectParser startElement(String namespace, String name, String defaultNamespace, Attributes attributes) throws SAXException {
+		if (!allowChildren())
+			throw new SAXException("unexpected child {"+namespace+"}"+name+" at "+path);
+		else
+			return null;
+	}
+	
+	public void endElement(String namespace, String name) throws SAXException {
+		
+	}
+
+	public void endChild(XMLObjectParser child) throws SAXException {
+	}
+
+	public boolean allowChildren() {
+		return false;
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	public void setPath(String path) {
+		this.path = path;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLStringParser.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLStringParser.java
new file mode 100644
index 0000000..8a0b704
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLStringParser.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml;
+
+import org.xml.sax.SAXException;
+
+public abstract class XMLStringParser extends XMLObjectParser {
+
+	private final StringBuilder content = new StringBuilder();
+	
+	public void findText(char[] ch, int start, int length, boolean whitespace) throws SAXException {
+		content.append(ch, start, length); 
+	}
+
+	public String getContent() {
+		return content.toString();
+	}
+
+	public boolean hasText() throws SAXException {
+		return true;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLUtil.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLUtil.java
new file mode 100644
index 0000000..9da2fa4
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/XMLUtil.java
@@ -0,0 +1,244 @@
+package org.eclipse.uomo.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public final class XMLUtil {
+
+	private XMLUtil() {}
+	
+	public static boolean isNMToken(String name) {
+		if (name == null)
+			return false;
+		for (int i = 0; i < name.length(); i++) 
+			if (!isNMTokenChar(name.charAt(i)))
+				return false;	
+		return name.length() > 0;
+	}
+
+	public static boolean isNMTokenChar(char c) {
+		return isLetter(c) || isDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isCombiningChar(c) || isExtender(c);
+	}
+
+	private static boolean isDigit(char c) {
+		return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9') || 
+			(c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F') || 
+			(c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF') || 
+			(c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F') || 
+			(c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
+	}
+
+	private static boolean isCombiningChar(char c) {
+		return (c >= '\u0300' && c <= '\u0345') || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') || 
+			(c >= '\u0591' && c <= '\u05A1') || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD') || 
+			c == '\u05BF' || (c >= '\u05C1' && c <= '\u05C2') || c == '\u05C4' || (c >= '\u064B' && c <= '\u0652') || 
+			c == '\u0670' || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4') || 
+			(c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903') || c == '\u093C' || 
+			(c >= '\u093E' && c <= '\u094C') || c == '\u094D' || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') || 
+			(c >= '\u0981' && c <= '\u0983') || c == '\u09BC' || c == '\u09BE' || c == '\u09BF' || (c >= '\u09C0' && c <= '\u09C4') || 
+			(c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD') || c == '\u09D7' || (c >= '\u09E2' && c <= '\u09E3') || 
+			c == '\u0A02' || c == '\u0A3C' || c == '\u0A3E' || c == '\u0A3F' || (c >= '\u0A40' && c <= '\u0A42') || 
+			(c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D') || (c >= '\u0A70' && c <= '\u0A71') || 
+			(c >= '\u0A81' && c <= '\u0A83') || c == '\u0ABC' || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') || 
+			(c >= '\u0ACB' && c <= '\u0ACD') || (c >= '\u0B01' && c <= '\u0B03') || c == '\u0B3C' || (c >= '\u0B3E' && c <= '\u0B43') || 
+			(c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D') || (c >= '\u0B56' && c <= '\u0B57') || 
+			(c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2') || (c >= '\u0BC6' && c <= '\u0BC8') || 
+			(c >= '\u0BCA' && c <= '\u0BCD') || c == '\u0BD7' || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') || 
+			(c >= '\u0C46' && c <= '\u0C48') || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') || 
+			(c >= '\u0C82' && c <= '\u0C83') || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') || 
+			(c >= '\u0CCA' && c <= '\u0CCD') || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') || 
+			(c >= '\u0D3E' && c <= '\u0D43') || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D') || c == '\u0D57' || 
+			c == '\u0E31' || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E') || c == '\u0EB1' || 
+			(c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD') || 
+			(c >= '\u0F18' && c <= '\u0F19') || c == '\u0F35' || c == '\u0F37' || c == '\u0F39' || c == '\u0F3E' || c == '\u0F3F' || 
+			(c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95') || c == '\u0F97' || 
+			(c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7') || c == '\u0FB9' || (c >= '\u20D0' && c <= '\u20DC') ||
+			c == '\u20E1' || (c >= '\u302A' && c <= '\u302F') || c == '\u3099' || c == '\u309A';
+	}
+
+	private static boolean isExtender(char c) {
+		return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387' || c == '\u0640' || c == '\u0E46' || 
+			c == '\u0EC6' || c == '\u3005' || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') || 
+			(c >= '\u30FC' && c <= '\u30FE');
+	}
+
+	private static boolean isLetter(char c) {
+		return isBaseChar(c) || isIdeographic(c);
+	}
+
+	private static boolean isBaseChar(char c) {
+		return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A') || (c >= '\u00C0' && c <= '\u00D6') || 
+			(c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131') || 
+			(c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E') || 
+			(c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5') || 
+			(c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1') || 
+			c == '\u0386' || (c >= '\u0388' && c <= '\u038A') || c == '\u038C' || (c >= '\u038E' && c <= '\u03A1') || 
+			(c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6') || c == '\u03DA' || c == '\u03DC' || c == '\u03DE' || 
+			c == '\u03E0' || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F') || 
+			(c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4') || 
+			(c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB') || 
+			(c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556') || 
+			c == '\u0559' || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2') || 
+			(c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7') || 
+			(c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3') || 
+			c == '\u06D5' || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939') || c == '\u093D' || 
+			(c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990') || 
+			(c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0') || c == '\u09B2' || 
+			(c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DC' && c <= '\u09DD') || (c >= '\u09DF' && c <= '\u09E1') || 
+			(c >= '\u09F0' && c <= '\u09F1') || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') || 
+			(c >= '\u0A13' && c <= '\u0A28') || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') || 
+			(c >= '\u0A35' && c <= '\u0A36') || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C') || 
+			c == '\u0A5E' || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B') || c == '\u0A8D' || 
+			(c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0') || 
+			(c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9') || c == '\u0ABD' || c == '\u0AE0' || 
+			(c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28') || 
+			(c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39') || 
+			c == '\u0B3D' || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') || 
+			(c >= '\u0B85' && c <= '\u0B8A') || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') || 
+			(c >= '\u0B99' && c <= '\u0B9A') || c == '\u0B9C' || (c >= '\u0B9E' && c <= '\u0B9F') || 
+			(c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA') || (c >= '\u0BAE' && c <= '\u0BB5') || 
+			(c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C') || (c >= '\u0C0E' && c <= '\u0C10') || 
+			(c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33') || (c >= '\u0C35' && c <= '\u0C39') || 
+			(c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C') || (c >= '\u0C8E' && c <= '\u0C90') || 
+			(c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3') || (c >= '\u0CB5' && c <= '\u0CB9') || 
+			c == '\u0CDE' || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') || 
+			(c >= '\u0D0E' && c <= '\u0D10') || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') || 
+			(c >= '\u0D60' && c <= '\u0D61') || (c >= '\u0E01' && c <= '\u0E2E') || c == '\u0E30' || 
+			(c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82') || 
+			c == '\u0E84' || (c >= '\u0E87' && c <= '\u0E88') || c == '\u0E8A' || c == '\u0E8D' || (c >= '\u0E94' && c <= '\u0E97') || 
+			(c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3') || c == '\u0EA5' || c == '\u0EA7' || 
+			(c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE') || c == '\u0EB0' || 
+			(c >= '\u0EB2' && c <= '\u0EB3') || c == '\u0EBD' || (c >= '\u0EC0' && c <= '\u0EC4') || 
+			(c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69') || (c >= '\u10A0' && c <= '\u10C5') || 
+			(c >= '\u10D0' && c <= '\u10F6') || c == '\u1100' || (c >= '\u1102' && c <= '\u1103') || 
+			(c >= '\u1105' && c <= '\u1107') || c == '\u1109' || (c >= '\u110B' && c <= '\u110C') || 
+			(c >= '\u110E' && c <= '\u1112') || c == '\u113C' || c == '\u113E' || c == '\u1140' || c == '\u114C' || 
+			c == '\u114E' || c == '\u1150' || (c >= '\u1154' && c <= '\u1155') || c == '\u1159' || 
+			(c >= '\u115F' && c <= '\u1161') || c == '\u1163' || c == '\u1165' || c == '\u1167' || c == '\u1169' || 
+			(c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173') || c == '\u1175' || 
+			c == '\u119E' || c == '\u11A8' || c == '\u11AB' || (c >= '\u11AE' && c <= '\u11AF') || 
+			(c >= '\u11B7' && c <= '\u11B8') || c == '\u11BA' || (c >= '\u11BC' && c <= '\u11C2') || 
+			c == '\u11EB' || c == '\u11F0' || c == '\u11F9' || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') || 
+			(c >= '\u1F00' && c <= '\u1F15') || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') || 
+			(c >= '\u1F48' && c <= '\u1F4D') || (c >= '\u1F50' && c <= '\u1F57') || c == '\u1F59' || c == '\u1F5B' || c == '\u1F5D' || 
+			(c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC') || 
+			c == '\u1FBE' || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') || 
+			(c >= '\u1FD0' && c <= '\u1FD3') || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') || 
+			(c >= '\u1FF2' && c <= '\u1FF4') || (c >= '\u1FF6' && c <= '\u1FFC') || c == '\u2126' || 
+			(c >= '\u212A' && c <= '\u212B') || c == '\u212E' || (c >= '\u2180' && c <= '\u2182') || 
+			(c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA') || (c >= '\u3105' && c <= '\u312C') || 
+			(c >= '\uAC00' && c <= '\uD7A3');
+	}
+
+	private static boolean isIdeographic(char c) {
+		return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
+	}
+
+	public static String determineEncoding(InputStream stream) throws IOException {
+		stream.mark(20000);
+		try {
+			int b0 = stream.read();
+			int b1 = stream.read();
+			int b2 = stream.read();
+			int b3 = stream.read();
+
+			if (b0 == 0xFE && b1 == 0xFF)
+				return "UTF-16BE"; //$NON-NLS-1$
+			else if (b0 == 0xFF && b1 == 0xFE)
+				return "UTF-16LE"; //$NON-NLS-1$
+			else if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF )
+				return "UTF-8"; //$NON-NLS-1$
+			else if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F)
+				return "UTF-16BE"; //$NON-NLS-1$
+			else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00)
+				return "UTF-16LE"; //$NON-NLS-1$
+			else if (b0 == 0x3C && b1 == 0x3F && b2 == 0x78 && b3 == 0x6D) {
+//				UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding 
+//				which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding 
+//				declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns 
+//				for the relevant ASCII characters, the encoding declaration itself may be read reliably
+				InputStreamReader rdr = new InputStreamReader(stream, "US-ASCII"); //$NON-NLS-1$
+				String hdr = readFirstLine(rdr);
+				return extractEncoding(hdr); 
+			} else
+				return null;
+		} finally {
+			stream.reset();
+		}
+	}
+
+	private static String extractEncoding(String hdr) {
+		int i = hdr.indexOf("encoding="); //$NON-NLS-1$
+		if (i == -1)
+			return null;
+		hdr = hdr.substring(i+9);
+		char sep = hdr.charAt(0);
+		hdr = hdr.substring(1);
+		i = hdr.indexOf(sep);
+		if (i == -1)
+			return null;
+		return hdr.substring(0, i);
+	}
+
+	private static String readFirstLine(InputStreamReader rdr) throws IOException {
+		char[] buf = new char[1];
+		StringBuffer bldr = new StringBuffer();
+		rdr.read(buf);
+		while (buf[0] != '>') {
+			bldr.append(buf[0]);
+			rdr.read(buf);
+		}
+		return bldr.toString();
+	}
+
+	
+    public static boolean charSetImpliesAscii(String charset) {
+		return charset.equals("ISO-8859-1") || charset.equals("US-ASCII"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	
+	/**
+	 * Converts the raw characters to XML escape characters.
+	 * 
+	 * @param rawContent
+	 * @param charset Null when charset is not known, so we assume it's unicode
+	 * @param isNoLines
+	 * @return escape string
+	 */
+	public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
+		if (rawContent == null)
+			return ""; //$NON-NLS-1$
+		else {
+			StringBuffer sb = new StringBuffer();
+
+			for (int i = 0; i < rawContent.length(); i++) {
+				char ch = rawContent.charAt(i);
+				if (ch == '\'')
+					sb.append("&#39;"); //$NON-NLS-1$
+				else if (ch == '&')
+					sb.append("&amp;"); //$NON-NLS-1$
+				else if (ch == '"')
+					sb.append("&quot;"); //$NON-NLS-1$
+				else if (ch == '<')
+					sb.append("&lt;"); //$NON-NLS-1$
+				else if (ch == '>')
+					sb.append("&gt;"); //$NON-NLS-1$
+				else if (ch > '~' && charset != null && charSetImpliesAscii(charset)) 
+					// TODO - why is hashcode the only way to get the unicode number for the character
+					// in jre 5.0?
+					sb.append("&#x"+Integer.toHexString(new Character(ch).hashCode()).toUpperCase()+";"); //$NON-NLS-1$ //$NON-NLS-2$
+				else if (isNoLines) {
+					if (ch == '\r')
+						sb.append("&#xA;"); //$NON-NLS-1$
+					else if (ch != '\n')
+						sb.append(ch);
+				}
+				else
+					sb.append(ch);
+			}
+			return sb.toString();
+		}
+	}
+	
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMParserWithPosition.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMParserWithPosition.java
new file mode 100644
index 0000000..6e44068
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMParserWithPosition.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2010, 2010, Copyright (c) 2010, 2010 Kestral Computing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.NamespaceContext;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLAttributes;
+import org.apache.xerces.xni.XMLLocator;
+import org.apache.xerces.xni.XMLString;
+import org.apache.xerces.xni.XNIException;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+/**
+ * @author dennisn
+ * 
+ */
+public class DOMParserWithPosition extends DOMParser {
+
+	/**
+	 * Constants used to find the start line in element's user data
+	 */
+	public static final String START_LINE = "startLine"; //$NON-NLS-1$
+	public static final String START_COLUMN = "startColumn"; //$NON-NLS-1$
+	public static final String END_LINE = "endLine"; //$NON-NLS-1$
+	public static final String END_COLUMN = "endColumn"; //$NON-NLS-1$
+
+	private static boolean NotIncludeIgnorableWhiteSpaces = false;
+	private XMLLocator locator;
+
+	// constructor
+	public DOMParserWithPosition() throws SAXNotRecognizedException,
+			SAXNotSupportedException {
+		this.setFeature(
+				"http://apache.org/xml/features/dom/defer-node-expansion", false); //$NON-NLS-1$
+	}
+
+	/* Methods that we override */
+
+	/* We override startElement/endElement callback from DocumentHandler */
+	public void startElement(QName elementQName, XMLAttributes attrList,
+			Augmentations augs) throws XNIException {
+		super.startElement(elementQName, attrList, augs);
+
+		Node node = getCurrentNode();
+		if (node != null) {
+			// Save location into node
+			node.setUserData(START_LINE, new Integer(locator.getLineNumber()),
+					null);
+			node.setUserData(START_COLUMN,
+					new Integer(locator.getColumnNumber()), null);
+		}
+	}
+
+	public void endElement(QName elementQName, Augmentations augs)
+			throws XNIException {
+		super.endElement(elementQName, augs);
+
+		Node node = getCurrentNode();
+		if (node != null) {
+			// Save location into node
+			node.setUserData(END_LINE, new Integer(locator.getLineNumber()),
+					null);
+			node.setUserData(END_COLUMN,
+					new Integer(locator.getColumnNumber()), null);
+		}
+	}
+
+	/* We override startDocument/endDocument callback from DocumentHandler */
+	public void startDocument(XMLLocator locator, String encoding,
+			NamespaceContext namespaceContext, Augmentations augs)
+			throws XNIException {
+		super.startDocument(locator, encoding, namespaceContext, augs);
+		this.locator = locator;
+		Node node = getCurrentNode();
+		if (node != null)
+			node.setUserData(START_LINE, new Integer(locator.getLineNumber()),
+					null); // Save location String into node
+	}
+
+	public void endDocument(Augmentations augs) throws XNIException {
+		super.endDocument(augs);
+		Node node = getCurrentNode();
+		if (node != null)
+			node.setUserData(START_LINE, new Integer(locator.getLineNumber()),
+					null); // Save location String into node
+	}
+
+	private Node getCurrentNode() {
+		try {
+			return (Node) this
+					.getProperty("http://apache.org/xml/properties/dom/current-element-node"); //$NON-NLS-1$
+		} catch (org.xml.sax.SAXException ex) {
+			System.err.println("except" + ex);; //$NON-NLS-1$
+			return null;
+		}
+	}
+
+	public void ignorableWhitespace(XMLString text, Augmentations augs)
+			throws XNIException {
+		if (!NotIncludeIgnorableWhiteSpaces)
+			super.ignorableWhitespace(text, augs);
+		else
+			;// Ignore ignorable white spaces
+	}
+
+	// Static utility methods to facilitate accessing node value
+	public static Integer getNodeLocation(Node node, String locationId,
+			Integer defaultValue) {
+		if (node != null && node.getUserData(locationId) instanceof Integer) {
+			return (Integer) node.getUserData(locationId);
+		}
+		return defaultValue;
+	}
+
+	public static Integer getNodeStartLine(Node node, Integer defaultValue) {
+		return getNodeLocation(node, START_LINE, defaultValue);
+	}
+
+	public static Integer getNodeStartColumn(Node node, Integer defaultValue) {
+		return getNodeLocation(node, START_COLUMN, defaultValue);
+	}
+
+	public static Integer getNodeEndLine(Node node, Integer defaultValue) {
+		return getNodeLocation(node, END_LINE, defaultValue);
+	}
+
+	public static Integer getNodeEndColumn(Node node, Integer defaultValue) {
+		return getNodeLocation(node, END_COLUMN, defaultValue);
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMXMLWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMXMLWriter.java
new file mode 100644
index 0000000..c01bec4
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/DOMXMLWriter.java
@@ -0,0 +1,527 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2009, 2009, Copyright (c) 2009, 2009 Kestral Computing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Kestral Computing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.uomo.xml.DOMUtil;
+import org.eclipse.uomo.xml.IXMLWriter;
+import org.eclipse.uomo.xml.XMLUtil;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A DOM-base XML writer
+ * 
+ * @author dennisn
+ *
+ */
+public class DOMXMLWriter implements IXMLWriter {
+	
+	/**
+	 * The internal document
+	 */
+	private Document doc = null;
+	
+	private boolean isPretty = true;
+	
+	// the current stack of element
+	private Stack<Node> current = new Stack<Node>();
+	
+	// defined attributes for the new coming element
+	private Map attributes = new HashMap();
+	
+	// the defined namespace for the new coming element
+	private Map definedNS = new HashMap();
+	
+	private DocumentFragment commentBlock = null;
+	
+	public DOMXMLWriter() throws ParserConfigurationException {
+		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+		builderFactory.setNamespaceAware(true);
+		DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
+		doc = docBuilder.newDocument();
+	}
+	
+	public DOMXMLWriter(Document doc) {
+		this.doc = doc;
+	}
+	
+	/**
+	 * @return the internal document
+	 * NOTE: be careful when changing the internal document, as it may
+	 * cause error for the writer
+	 */
+	public Document getDOMDocument() {
+		return doc;
+	}
+	
+	public Element getCurrentElement() {
+		return (Element) current.peek();
+	}
+	
+	protected boolean condition(boolean bTest, String message) throws IOException {
+		if (!bTest)
+			throw new IOException(message);
+		return bTest;
+	}
+	
+	private void addAttribute(String name, String value) throws IOException {
+		addAttribute(name, value, false);
+	}
+
+	private void addAttribute(String name, String value, boolean isNoLines) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+
+		condition(!attributes.containsKey(name), "attempt to define attribute with name "+name+" more than once");
+		attributes.put(name, XMLUtil.escapeXML(value, null, isNoLines));
+	}
+	
+	private void defineNamespace(String namespace, String prefix) {
+		if (namespace != null) {
+			if (prefix == null)
+				prefix = "";
+			
+			definedNS.put(prefix, namespace);
+		}
+	}
+	
+	private String getPrefixForNamespace(String namespace) throws IOException {
+		if ("http://www.w3.org/XML/1998/namespace".equals(namespace))
+			return "xml:";
+
+		String prefix = null;
+		if (definedNS.containsValue(namespace)) {
+			Iterator iter = definedNS.keySet().iterator();
+			while (prefix == null && iter.hasNext()) {
+				Object k = iter.next();
+				if (definedNS.get(k).equals(namespace))
+					prefix = k.toString();
+			}
+		}
+		else if (current.size() > 0)
+			prefix = DOMUtil.lookupPrefixForNamespace((Element) current.peek(), namespace);
+		
+		if (prefix == null)
+			throw new IOException("Namespace "+namespace+" is not defined");
+		return prefix + ":";
+	}
+	
+	private String getNamespaceForPrefix(String prefix) throws IOException {
+		if ("xml".equals(prefix))
+			return "http://www.w3.org/XML/1998/namespace";
+
+		String result = null;
+		if (definedNS.containsKey(prefix))
+			result = definedNS.get(prefix).toString();
+		else if (current.size() > 0)
+			prefix = DOMUtil.lookupNamespaceForPrefix((Element) current.peek(), prefix);
+		return result == null ? "" : result;
+	}
+	
+	private void checkInElement() throws IOException {
+		condition(current != null && current.size() > 0, "Not in an element");
+	}
+
+	// IXMLWriter methods
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#abbreviationDefined(java.lang.String)
+	 */
+	public boolean abbreviationDefined(String abbreviation) {
+		return definedNS.containsKey(abbreviation) 
+			|| (current.size() > 0 && DOMUtil.lookupNamespaceForPrefix(getCurrentElement(), abbreviation) != null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String, boolean)
+	 */
+	public void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || value != null && !value.equals(""))
+			attribute(namespace, name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void attribute(String namespace, String name, String value) throws IOException {
+		if (namespace == null || namespace.equals("")) 
+			addAttribute(name, value);
+		else
+			addAttribute(getPrefixForNamespace(namespace)+name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, boolean)
+	 */
+	public void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || value != null && !value.equals(""))
+			attribute(name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String)
+	 */
+	public void attribute(String name, String value) throws IOException {
+		addAttribute(name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attributeNoLines(java.lang.String, java.lang.String)
+	 */
+	public void attributeNoLines(String name, String value) throws IOException {
+		addAttribute(name, value, true);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#cData(java.lang.String)
+	 */
+	public void cData(String text) throws IOException {
+		checkInElement();
+		getCurrentElement().appendChild(doc.createCDATASection(text));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close(java.lang.String)
+	 */
+	public void close(String name) throws IOException {
+		if (current.size() == 0)
+			throw new IOException("Unable to close null|"+name+", nothing to close");
+		if (!getCurrentElement().getNodeName().equals(name))
+			throw new IOException("Unable to close null|"+name+", found "+getCurrentElement().getNodeName());
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close(java.lang.String, java.lang.String)
+	 */
+	public void close(String namespace, String name) throws IOException {
+		if (current.size() == 0)
+			throw new IOException("Unable to close null|"+name+", nothing to close");
+		// assume current is DOM level 3
+		Element ele = getCurrentElement();
+		if (!namespace.equals(ele.getNamespaceURI()) || !name.equals(ele.getLocalName()))
+			throw new IOException("Unable to close "+namespace+"|"+name+", found "+ele.getNamespaceURI() +"|"+ele.getLocalName());
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close()
+	 */
+	public void close() throws IOException {
+		checkInElement();
+		current.pop();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#closeToLevel(int)
+	 */
+	public void closeToLevel(int count) throws IOException {
+		while (current.size() > count)
+			close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#comment(java.lang.String, boolean)
+	 */
+	public void comment(String comment, boolean doPretty) throws IOException {
+		Comment c = doc.createComment(comment);
+		getCurrentElement().appendChild(c);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, boolean)
+	 */
+	public void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || content != null && !content.equals(""))
+			element(namespace, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void element(String namespace, String name, String content, String comment) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		open(namespace, name, comment);
+		text(content);
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void element(String namespace, String name, String content) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		open(namespace, name);
+		text(content);
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, boolean)
+	 */
+	public void element(String name, String content, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || content != null && !content.equals(""))
+			element(null, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String)
+	 */
+	public void element(String name, String content) throws IOException {
+		element(null, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#endCommentBlock()
+	 */
+	public void endCommentBlock() throws IOException {
+		if (commentBlock == null)
+			throw new IOException("Cannot close a comment block when none existed");
+		else if (getCurrentElement().getParentNode() != commentBlock)
+			throw new IOException("Cannot close a comment block when it's still opened");
+		
+		ByteArrayOutputStream temp = new ByteArrayOutputStream();
+		try {
+			// re-create the comment nodes
+			NodeList children = getCurrentElement().getChildNodes();
+			DocumentFragment frag = doc.createDocumentFragment();
+			for (int i = 0; i < children.getLength(); i++) 
+				frag.appendChild(children.item(i));
+			
+			// init DOM->String transformer
+			Transformer trans = TransformerFactory.newInstance().newTransformer();
+			trans.setOutputProperty(OutputKeys.STANDALONE, "no");
+			trans.setOutputProperty(OutputKeys.INDENT, "yes");
+			trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+
+			// convert from DOM to string comment
+			
+			trans.transform(new DOMSource(frag), new StreamResult(temp));
+		}
+		catch (Exception e) {
+			throw new IOException(e.getLocalizedMessage());
+		}
+		finally {
+			current.pop();
+			commentBlock = null;
+		}
+		comment(temp.toString(), true);
+	}
+
+//	/* (non-Javadoc)
+//	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#escapedText(java.lang.String)
+//	 */
+//	public void escapedText(String content) throws IOException {
+//		checkInElement();
+//		text(content);
+//	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#getDefaultNamespace()
+	 */
+	public String getDefaultNamespace() {
+		String result = null;
+		if (definedNS.size() > 0) {
+			try {
+				result = getNamespaceForPrefix("");
+			} catch (IOException e) {
+				// do nothing
+			}
+		}
+		
+		if (result == null && current.size() > 0)
+			result = DOMUtil.lookupNamespaceForPrefix(getCurrentElement(), "");
+		
+		return result == null ? "": result;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#isPretty()
+	 */
+	public boolean isPretty() throws IOException {
+		return isPretty;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespace(java.lang.String)
+	 */
+	public void namespace(String namespace) throws IOException {
+		if (!namespaceDefined(namespace)) {
+			int index = 0;
+			while (abbreviationDefined("ns"+Integer.toString(index))) 
+				index++;
+			defineNamespace(namespace, "ns"+Integer.toString(index));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespace(java.lang.String, java.lang.String)
+	 */
+	public void namespace(String namespace, String prefix) throws IOException {
+		String ns = getNamespaceForPrefix(prefix);
+		if (ns == null || !ns.equals(namespace))
+			defineNamespace(namespace, prefix);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespaceDefined(java.lang.String)
+	 */
+	public boolean namespaceDefined(String namespace) {
+		try {
+			return getPrefixForNamespace(namespace) != null;
+		} catch (IOException e) {
+			return false;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String, java.lang.String)
+	 */
+	public void open(String namespace, String name) throws IOException {
+		open(namespace, name, null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void open(String namespace, String name, String comment) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		if (name == null)
+			throw new IOException("XML name is null");
+
+		Element ele;
+		if (namespace != null) {
+			name = getPrefixForNamespace(namespace) + name;
+			ele = doc.createElementNS(namespace, name);
+		}
+		else if (getDefaultNamespace().length() > 0)
+			ele = doc.createElementNS(getDefaultNamespace(), name);
+		else
+			ele = doc.createElement(name);
+		defineAttributes(ele);
+		defineNamespaces(ele);
+		if (current.size() == 0)
+			doc.appendChild(ele);
+		else
+			getCurrentElement().appendChild(ele);
+		current.push(ele);
+		if (comment != null) comment(comment, true);
+	}
+
+	private void defineNamespaces(Element ele) {
+		Iterator<?> iter = definedNS.keySet().iterator();
+		while (iter.hasNext()) {
+			Object k = iter.next();
+			ele.setAttribute("xmlns:" + k.toString(), definedNS.get(k).toString());
+		}
+		definedNS.clear();
+	}
+
+	private void defineAttributes(Element ele) {
+		Iterator<?> iter = attributes.keySet().iterator();
+		while (iter.hasNext()) {
+			Object k = iter.next();
+			ele.setAttribute(k.toString(), attributes.get(k).toString());
+		}
+		attributes.clear();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String)
+	 */
+	public void open(String name) throws IOException {
+		open(null, name);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#setDefaultNamespace(java.lang.String)
+	 */
+	public void setDefaultNamespace(String namespace) throws IOException {
+		if ((namespace == null && getDefaultNamespace() != null) ||
+				(namespace != null && !namespace.equals(getDefaultNamespace())))
+			defineNamespace(namespace, "");
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#setPretty(boolean)
+	 */
+	public void setPretty(boolean pretty) throws IOException {
+		this.isPretty = pretty;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#start()
+	 */
+	public void start() throws IOException {
+		// dont need to do anything
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#startCommentBlock()
+	 */
+	public void startCommentBlock() throws IOException {
+		if (commentBlock != null)
+			throw new IOException("Cannot nest comments");
+		/* we start a comment block by create a document fragment with 1 element root: commentRoot
+		 * Further node will be add to be children of this element root.
+		 */
+		commentBlock = doc.createDocumentFragment();
+		Node node = doc.createElement("commentRoot");
+		commentBlock.appendChild(node);
+		current.push(node);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#text(java.lang.String)
+	 */
+	public void text(String content) throws IOException {
+		text(content, false);
+	}
+	
+	public void text(String content, boolean dontEscape) throws IOException {
+		if (!dontEscape)
+			content = XMLUtil.escapeXML(content, null, false);
+		checkInElement();
+		Node node = doc.createTextNode(content);
+		getCurrentElement().appendChild(node);	
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#writeBytes(byte[])
+	 */
+	public void writeBytes(byte[] bytes) throws IOException {
+		text(new String(bytes));
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XHTMLWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XHTMLWriter.java
new file mode 100644
index 0000000..c68c0ba
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XHTMLWriter.java
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+ 
+//import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * XHTML Writer 
+ * 
+ *
+ */
+class XHTMLWriter extends XMLWriter {
+
+	public final static String NS_XHTML = "http://www.w3.org/1999/xhtml";
+	public final static int NULL_INTEGER = -1;
+	
+	private String headerStyle = null;
+	
+	public XHTMLWriter(OutputStream stream, String charset) throws IOException {
+		super(stream, charset);
+		setPretty(true);
+		setLineType(LINE_WINDOWS);
+	}
+
+	// -- CSS -----------------------------------------------------------
+	
+	private List styles = new ArrayList();
+	
+	private class StyleDetail {
+		private String name;
+		private String value;
+	}
+
+	// override
+	protected void commitAttributes() throws IOException {
+		String s = grabStyles();
+		if (s != null) {
+			String attr = getAttribute("style");
+			setAttribute("style", attr == null ? s : attr+"; "+s);
+		}
+	}
+
+	public String grabStyles() {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < styles.size(); i++) {
+			StyleDetail det = (StyleDetail) styles.get(i);
+			if (i > 0)
+				buffer.append(' ');
+			buffer.append(det.name);
+			buffer.append(": ");
+			buffer.append(det.value);
+			buffer.append(';');
+		}
+		styles.clear();
+		return buffer.toString();
+	}
+
+	public void cssStyle(String name, String value) {
+		StyleDetail det;
+		for (int i = 0; i < styles.size(); i++) {
+			det = (StyleDetail) styles.get(i);
+			if (det.name.equals(name)) {
+				det.value = value;
+				return;
+			}
+		}
+		det = new StyleDetail();
+		det.name = name;
+		det.value = value;
+		styles.add(det);		
+	}
+		
+	public void cssStyle(String name, boolean value) {
+		cssStyle(name, Boolean.toString(value));
+	}
+	
+	public void cssStyle(String name, int value) {
+		cssStyle(name, Integer.toString(value));
+	}
+
+	//-- HTML -----------------------------------------------------------
+	
+	public void start() throws IOException {
+		super.start();
+		setDefaultNamespace(NS_XHTML);
+	}
+
+	public void openDiv(String style) throws IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "div");
+	}
+
+	public void closeDiv() throws IOException, IOException {
+		close(NS_XHTML, "div");
+	}
+
+	public void openSpan(String style) throws IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "span");
+	}
+
+	public void closeSpan() throws IOException, IOException {
+		close(NS_XHTML, "span");
+	}
+
+	public void span(String style, String content) throws IOException, IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+
+		element(NS_XHTML, "span", content);
+	}
+
+	public void nonBreakingSpace(int count) throws IOException {
+		for (int i = 0; i < count; i++)
+			text("&nbsp;");		
+	}
+
+	public void paragraph() throws IOException, IOException {
+		element(NS_XHTML, "p", null);		
+	}
+
+	public void paragraph(String content) throws IOException, IOException {
+		element(NS_XHTML, "p", content);		
+	}
+
+	
+	public void header(int level, String content) throws IOException, IOException {
+		if (headerStyle != null)
+			attribute(NS_XHTML, "style", headerStyle);
+		element(NS_XHTML, "h"+Integer.toString(level), content);		
+	}
+
+	public void anchor(String url, String content,String style) throws IOException, IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		anchor(url, content);
+	}
+	
+	public void anchor(String anchor) throws IOException, IOException {
+		attribute(NS_XHTML, "name", anchor);
+		element(NS_XHTML, "a", null);		
+	}
+	
+	public void openAnchor() throws IOException {
+		open(NS_XHTML, "a");		
+	}
+	
+	public void closeAnchor() throws IOException {
+		close(NS_XHTML, "a");		
+	}
+	
+	public void anchor(String url, String content) throws IOException, IOException {
+		attribute(NS_XHTML, "href", url);
+		element(NS_XHTML, "a", content);		
+	}
+
+	public void br() throws IOException, IOException {
+		element(NS_XHTML, "br", null);		
+	}
+
+	public void openTable(int border, int padding, int spacing, int width, String style) throws IOException {
+		if (border != NULL_INTEGER)
+			attribute(NS_XHTML, "border", Integer.toString(border));
+		if (padding != NULL_INTEGER)
+			attribute(NS_XHTML, "cellpadding", Integer.toString(border));
+		if (spacing != NULL_INTEGER)
+			attribute(NS_XHTML, "cellspacing", Integer.toString(border));
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		if (width != NULL_INTEGER)
+			attribute(NS_XHTML, "width", Integer.toString(width)+"%");
+		open(NS_XHTML, "table");
+	}
+
+	public void closeTable() throws IOException, IOException {
+		close(NS_XHTML, "table");
+	}
+
+	public void openTableRow(String style) throws IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "tr");
+	}
+
+	public void openTableRow() throws IOException {
+		open(NS_XHTML, "tr");
+	}
+
+	public void openTableRow(int marker) throws IOException {
+		if (marker == -1)
+			attribute(NS_XHTML, "style", "font-weight: bold");
+		else if (marker == 1)
+			attribute(NS_XHTML, "style", "background-color:#E0E0E0");
+
+		open(NS_XHTML, "tr");
+	}
+
+	public void closeTableRow() throws IOException, IOException {
+		close(NS_XHTML, "tr");
+	}
+	
+	public void openTableCell() throws IOException {
+		openTableCell(null);
+	}
+	
+	public void closeTableCell() throws IOException, IOException {
+		close(NS_XHTML, "td");
+	}
+	
+	public void openTableCell(String style) throws IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "td");
+	}
+
+	public void openTableCell(int span, String style) throws IOException {
+		attribute(NS_XHTML, "colspan", Integer.toString(span));
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "td");
+	}
+
+
+	public void tableCellSpacer(int count, int colspan) throws IOException, IOException {
+		tableCellSpacer(null, count, colspan);		
+	}
+	
+	public void tableCellSpacer(int count) throws IOException, IOException {
+		tableCellSpacer(null, count, NULL_INTEGER);		
+	}
+	
+	public void tableCellSpacer(String style, int i) throws IOException, IOException {
+		tableCellSpacer(style, i, NULL_INTEGER);
+	}
+	
+	public void tableCellSpacer(String style, int i, int colspan) throws IOException, IOException {
+		if (colspan != NULL_INTEGER)
+			attribute(NS_XHTML, "colspan", Integer.toString(colspan));
+		
+		openTableCell(style);
+		nonBreakingSpace(i);
+		close();
+	}
+
+	public void tableCell(String content) throws IOException, IOException {
+		tableCell(null, content);
+	}
+
+	public void tableCell(String style, String content, String hint) throws IOException, IOException {
+		attribute(NS_XHTML, "title", hint);
+		tableCell(style, content);
+	}
+	public void tableCell(String style, String content) throws IOException, IOException {
+		openTableCell(style);
+		if (content == null)
+			nonBreakingSpace(1);
+		else
+			text(content);
+		close();		
+	}
+
+	public void openBlockQuote() throws IOException {
+		open(NS_XHTML, "blockQuote");	
+	}
+
+	public void closeBlockQuote() throws IOException, IOException {
+		close(NS_XHTML, "blockQuote");	
+	}
+
+	public void openList(boolean ordered) throws IOException {
+		open(NS_XHTML, ordered ? "ol" : "ul");
+		
+	}
+
+	public void closeList(boolean ordered) throws IOException, IOException {
+		close(NS_XHTML, ordered ? "ol" : "ul");
+		
+	}
+
+	public void openItem() throws IOException {
+		open(NS_XHTML, "li");
+	}
+
+	public void closeItem() throws IOException, IOException {
+		close(NS_XHTML, "li");
+	}
+
+	public void openHtml() throws IOException {
+		open(NS_XHTML, "html");
+	}
+
+	public void closeHtml() throws IOException, IOException {
+		close(NS_XHTML, "html");
+	}
+
+	public void openHead() throws IOException {
+		open(NS_XHTML, "head");
+	}
+
+
+	public void closeHead() throws IOException, IOException {
+		close(NS_XHTML, "head");
+	}
+
+	public void title(String title) throws IOException {
+		element(NS_XHTML, "title", title);
+	}
+
+	public void openBody() throws IOException {
+		openBody(null);
+	}
+
+	public void openBody(String style) throws IOException {
+		if (style != null)
+			attribute(NS_XHTML, "style", style);
+		open(NS_XHTML, "body");
+	}
+
+
+	public void closeBody() throws IOException, IOException {
+		close(NS_XHTML, "body");
+	}
+
+	public void openFont(String color) throws IOException {
+		attribute(NS_XHTML, "color", color);
+		open(NS_XHTML, "font");
+	}
+
+	public void closeFont() throws IOException, IOException {
+		close(NS_XHTML, "font");
+	}
+
+	public String getHeaderStyle() {
+		return headerStyle;
+	}
+
+	public void setHeaderStyle(String headerStyle) {
+		this.headerStyle = headerStyle;
+	}
+
+	public void image(String source) throws IOException {
+		attribute(NS_XHTML, "src", source);
+		element(NS_XHTML, "img", null);		
+	}
+
+	public void object(String source, String type, String altText, int width, int height) throws IOException {
+		attribute(NS_XHTML, "data", source);
+		attribute(NS_XHTML, "type", type);
+		attribute(NS_XHTML, "width", Integer.toString(width));
+		attribute(NS_XHTML, "height", Integer.toString(height));
+		element(NS_XHTML, "object", altText);
+	}
+
+	public void hr(int i) throws IOException {
+		attribute(NS_XHTML, "width", Integer.toString(i)+"%");
+		element(NS_XHTML, "hr", null);
+	}
+
+	public void openParagraph() throws IOException {
+		open(NS_XHTML, "p");
+	}
+
+	public void closeParagraph() throws IOException, IOException {
+		close(NS_XHTML, "p");
+	}
+
+	public void openBold() throws IOException {
+		open(NS_XHTML, "b");
+	}
+
+	public void closeBold() throws IOException, IOException {
+		close(NS_XHTML, "b");
+	}
+
+	public void openItalic() throws IOException {
+		open(NS_XHTML, "i");
+	}
+
+	public void closeItalic() throws IOException, IOException {
+		close(NS_XHTML, "i");
+	}
+
+	public void anchorDest(String id) throws IOException {
+		attribute(NS_XHTML, "name", id);
+		element(NS_XHTML, "a", null);
+	}
+
+	public void horizontalRule()  throws IOException {
+		element(NS_XHTML, "hr", null);
+	}
+
+	public void openStyle() throws IOException {
+		open(NS_XHTML, "STYLE");		
+	}
+
+	public void closeStyle() throws IOException {
+		close(NS_XHTML, "STYLE");		
+	}
+
+	public void openXhtmlTag(String tag) throws IOException {
+		open(NS_XHTML, tag);
+	}
+
+	public void closeXhtmlTag(String tag) throws IOException {
+		close(NS_XHTML, tag);
+	}
+
+
+}
+
+
+
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLBypassParser.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLBypassParser.java
new file mode 100644
index 0000000..227f612
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLBypassParser.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import org.eclipse.uomo.xml.XMLObjectParser;
+import org.xml.sax.SAXException;
+
+class XMLBypassParser extends XMLObjectParser {
+
+	public boolean hasText() throws SAXException {
+		return true;
+	}
+
+	public boolean allowChildren() {
+		return true;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLDomWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLDomWriter.java
new file mode 100644
index 0000000..5b8384d
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLDomWriter.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2010, Copyright (c) 2006, 2010 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *    Werner Keil  - usage of UnitException
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * @author Werner Keil
+ * @version 1.1 ($Revision: 63 $), $Date: 2010-07-19 11:35:31 +0100 (Mo, 19 Jul
+ *          2010) $
+ */
+public class XMLDomWriter {
+
+	private XMLWriter xml;
+
+	public XMLDomWriter(OutputStream stream)
+			throws UnsupportedEncodingException, IOException {
+		super();
+		xml = new XMLWriter(stream, "UTF-8");
+		xml.start();
+	}
+
+	public XMLDomWriter(XMLWriter writer) throws UnsupportedEncodingException {
+		super();
+		xml = writer;
+	}
+
+	public void write(Element element, boolean rootElement, String elementName,
+			String defaultNamespace) throws UOMoException, IOException {
+		if (defaultNamespace != null) {
+			if (!xml.namespaceDefined(defaultNamespace))
+				xml.setDefaultNamespace(defaultNamespace);
+		} else if (rootElement)
+			xml.setDefaultNamespace(element.getNamespaceURI());
+
+		if (elementName != null)
+			xml.open(defaultNamespace, elementName);
+
+		if (rootElement)
+			processElement(element);
+		else {
+			processContents(element);
+		}
+
+		if (elementName != null)
+			xml.close();
+		xml.flush();
+	}
+
+	private void processContents(Element element) throws UOMoException,
+			IOException {
+		Node node = element.getFirstChild();
+		while (node != null) {
+			switch (node.getNodeType()) {
+			case Node.ELEMENT_NODE:
+				processElement((Element) node);
+				break;
+			case Node.TEXT_NODE:
+				processText(node);
+				break;
+			case Node.COMMENT_NODE:
+				processComment((Comment) node);
+				break;
+			default:
+				throw new UOMoException("unhandled node type "
+						+ Integer.toString(node.getNodeType()));
+			}
+
+			node = node.getNextSibling();
+		}
+	}
+
+	private void processComment(Comment node) throws DOMException, IOException {
+		xml.comment(node.getNodeValue(), true);
+	}
+
+	private void processElement(Element element) throws UOMoException,
+			IOException {
+		xml.namespace(element.getNamespaceURI());
+
+		processAttributes(element);
+		xml.open(element.getNamespaceURI(), element.getLocalName());
+
+		processContents(element);
+
+		xml.close();
+	}
+
+	private void processText(Node node) throws UOMoException, IOException {
+		xml.text(node.getNodeValue());
+	}
+
+	private void processAttributes(Element element) throws IOException {
+		NamedNodeMap nodes = element.getAttributes();
+		for (int i = 0; i < nodes.getLength(); i++) {
+			Node attr = nodes.item(i);
+			if (attr.getNamespaceURI() != null) {
+				xml.namespace(attr.getNamespaceURI());
+				xml.attribute(attr.getNamespaceURI(), attr.getLocalName(),
+						attr.getNodeValue());
+			} else
+				xml.attribute(attr.getLocalName(), attr.getNodeValue());
+		}
+
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLElementIterator.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLElementIterator.java
new file mode 100644
index 0000000..8f88829
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLElementIterator.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class XMLElementIterator {
+
+	private NodeList nodes;
+	private int index;
+	
+	public XMLElementIterator(Element elem) {
+		super();
+		nodes = elem.getChildNodes();
+		index = -1;
+		next();
+	}
+
+	public boolean more() {
+		return index < nodes.getLength();
+	}
+
+	public Element current() {
+		return (Element)nodes.item(index);
+	}
+
+	public void next() {
+		do {
+			index++;
+		} while (index < nodes.getLength() && !(nodes.item(index) instanceof Element));
+	}
+  
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLNamespace.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLNamespace.java
new file mode 100644
index 0000000..85690bd
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLNamespace.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+public class XMLNamespace {
+
+	private String namespace;
+	private String abbreviation;
+	
+	public XMLNamespace(String namespace, String abbreviation) {
+		super();
+		setNamespace(namespace);
+		setAbbreviation(abbreviation);
+	}
+
+	public String getAbbreviation() {
+		return abbreviation;
+	}
+
+	public void setAbbreviation(String abbreviation) {
+		this.abbreviation = abbreviation;
+	}
+
+	public String getNamespace() {
+		return namespace;
+	}
+
+	public void setNamespace(String namespace) {
+		this.namespace = namespace;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLObjectParsers.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLObjectParsers.java
new file mode 100644
index 0000000..8c357c5
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLObjectParsers.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import org.eclipse.uomo.xml.XMLMessages;
+import org.eclipse.uomo.xml.XMLObjectParser;
+import org.xml.sax.SAXException;
+
+public class XMLObjectParsers {
+
+	private int stackTop = -1;
+	private int stackSize = 10;
+	private XMLObjectParser[] stack = new XMLObjectParser[10];
+
+	private void grow () {
+		XMLObjectParser[] temp = stack;
+		stackSize = stackSize + 10;
+		stack = new XMLObjectParser[stackSize];
+		for (int i = 0; i < stackSize - 10; i++)
+			stack[i] = temp[i];		
+	}
+	
+	public void push(XMLObjectParser handler) {
+		if (stackTop == stackSize -1)
+			grow();
+		stackTop++;
+		stack[stackTop] = handler;
+	}
+	
+	public void pop () throws SAXException {
+		if (stackTop == -1)
+			throw new SAXException(XMLMessages.XMLObjectParsers_stackUnderflow);
+		stackTop--;
+	}
+	
+	public XMLObjectParser current () throws SAXException {
+		if (stackTop == -1)
+			throw new SAXException(XMLMessages.XMLObjectParsers_stackUnderflow); //$NON-NLS-1$
+		return stack[stackTop];
+	}
+
+	public boolean hasCurrent() {
+		return stackTop >= 0;
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLPullWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLPullWriter.java
new file mode 100644
index 0000000..a5f781c
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLPullWriter.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.uomo.core.UOMoException;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class XMLPullWriter {
+
+	private XMLWriter xml;
+	
+	public XMLPullWriter(OutputStream stream) throws UnsupportedEncodingException, IOException {
+		super();
+		xml = new XMLWriter(stream, "UTF-8");
+		xml.start();
+	}
+
+	public XMLPullWriter(XMLWriter writer) throws UnsupportedEncodingException {
+		super();
+		xml = writer;
+	}
+
+	public void write(XmlPullParser xpp, boolean rootElement, String elementName, String defaultNamespace) throws UOMoException, IOException, XmlPullParserException {
+		if (defaultNamespace != null) {
+			if (!xml.namespaceDefined(defaultNamespace))
+				xml.setDefaultNamespace(defaultNamespace);
+		} else if (rootElement) 
+			xml.setDefaultNamespace(xpp.getNamespace());
+
+		if (elementName != null)
+			xml.open(defaultNamespace, elementName);
+		
+		if (rootElement)
+			processElement(xpp);
+		else {
+			processContents(xpp);
+			if (xpp.getEventType() != XmlPullParser.END_DOCUMENT)
+				xpp.next();
+		}
+		
+		if (elementName != null)
+			xml.close();
+		xml.flush();
+	}
+	
+	private void processContents(XmlPullParser xpp) throws XmlPullParserException, UOMoException, IOException {
+		while (xpp.getEventType() != XmlPullParser.END_TAG && xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
+			if (xpp.getEventType() == XmlPullParser.START_TAG)
+				processElement(xpp);
+			else if (xpp.getEventType() == XmlPullParser.TEXT)
+				processText(xpp);
+			else
+				throw new UOMoException("unhandled event type "+Integer.toString(xpp.getEventType()));
+		}
+	}
+
+	private void processElement(XmlPullParser xpp) throws UOMoException, XmlPullParserException, IOException {
+		xml.namespace(xpp.getNamespace());
+
+		processAttributes(xpp);
+		xml.open(xpp.getNamespace(), xpp.getName());
+		xpp.next();
+		
+		processContents(xpp);
+		
+		xml.close();
+		if (xpp.getEventType() != XmlPullParser.END_DOCUMENT)
+			xpp.next();
+	}
+
+	private void processText(XmlPullParser xpp) throws UOMoException, XmlPullParserException, IOException {
+		xml.text(xpp.getText());
+		xpp.next();
+	}
+
+	private void processAttributes(XmlPullParser xpp) throws IOException {
+		for (int i = 0; i < xpp.getAttributeCount(); i++) {
+			String ns = xpp.getAttributeNamespace(i);
+			if (!"".equals(ns)) {
+				xml.namespace(ns);
+     			xml.attribute(ns, xpp.getAttributeName(i), xpp.getAttributeValue(i));
+			} else 
+     			xml.attribute(xpp.getAttributeName(i), xpp.getAttributeValue(i));
+		}
+		
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLReader.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLReader.java
new file mode 100644
index 0000000..3c7b956
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLReader.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import java.io.InputStream;
+
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.uomo.xml.XMLObjectParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class XMLReader extends DefaultHandler {
+	
+	private XMLObjectParsers stack = new XMLObjectParsers();
+	private XMLObjectParser root;
+	
+	public XMLReader(XMLObjectParser handler) throws SAXException {
+		super();
+		root = handler;
+	}
+	
+	private XMLObjectParser current() throws SAXException {
+		return stack.current();
+	}
+	
+	public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+		XMLObjectParser handler;
+		String namespace;
+		String name;
+		if (uri == null || uri.equals("")) {
+			namespace = "";
+			name = qName;
+			
+		} else {
+			namespace = uri;
+			name = localName;
+		}
+		
+		if (!stack.hasCurrent()) {
+			if (root != null) {
+				stack.push(root);
+				root.setPath(name);
+				root.start(namespace, name, "", atts);
+				root = null;
+				current().use();
+			} else
+				throw new SAXException("no handler available");
+		} else {			
+			handler = current().startElement(namespace, name, "", atts);
+			if (handler == null)
+				current().use();
+			else {
+				handler.use();
+				handler.setPath(current().getPath() + "\\" + name);
+				handler.setNamespace(namespace);
+				handler.setName(name);
+				stack.push(handler);
+				current().start(namespace, name, "", atts);
+			}
+		}
+	}
+	
+	public void endElement(String uri, String localName, String qName) throws SAXException {
+		String namespace;
+		String name;
+		if (uri == null || uri.equals("")) {
+			namespace = "";
+			name = qName;
+			
+		} else {
+			namespace = uri;
+			name = localName;
+		}
+		if (current().unUse()) {
+			XMLObjectParser old = current();
+			old.end();
+			stack.pop();
+			if (stack.hasCurrent())
+				current().endChild(old);
+		} else
+			current().endElement(namespace, name);
+	}
+	
+	public void characters(char[] ch, int start, int length) throws SAXException {
+		current().findText(ch, start, length, StringUtils.isWhitespace(new String(ch, start, length)));
+		}
+	
+	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+		if (current().hasText())
+			current().findText(ch, start, length, true);
+	}
+
+	public void parse(InputStream stream) throws SAXException {
+		org.xml.sax.XMLReader xml;
+		try {
+			xml = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+			xml.setFeature("http://xml.org/sax/features/namespaces", true);
+			xml.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+			xml.setContentHandler(this);
+			xml.parse(new InputSource(stream));
+		} catch (Exception e) {
+			throw new SAXException(e);
+		}
+	}
+	
+	
+	
+	
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLStringsParser.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLStringsParser.java
new file mode 100644
index 0000000..651a181
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLStringsParser.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import org.eclipse.uomo.xml.XMLObjectParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class XMLStringsParser extends XMLObjectParser {
+
+	private String namespace;
+	private String name;
+	
+	private String[] content;
+	private StringBuffer current = null;
+	
+	
+	public XMLStringsParser(String namespace, String name) {
+		super();
+		this.namespace = namespace;
+		this.name = name;
+	}
+
+	public void endElement(String namespace, String name) throws SAXException {
+		if (current != null)
+			addContent(current.toString());
+			
+		current = null;
+	}
+
+	private void addContent(String string) {
+		if (content == null)
+			content = new String[] {string};
+		else {
+			String[] newContent = new String[content.length + 1];
+			for (int i = 0; i < content.length; i++)
+				newContent[i] = content[i];
+			newContent[content.length] = string;
+			content = newContent;
+		}
+	}
+
+	public XMLObjectParser startElement(String namespace, String name, String defaultNamespace, Attributes attributes) throws SAXException {
+		if (namespace.equals(this.namespace) && name.equals(this.name)) {
+			current = new StringBuffer();
+			return null;
+		}
+		else
+			return super.startElement(namespace, name, defaultNamespace, attributes);
+	}
+
+	public void findText(char[] ch, int start, int length, boolean whitespace) throws SAXException {
+		if (current == null)
+			super.findText(ch, start, length, whitespace);
+		else
+			current.append(ch, start, length); 
+	}
+
+	public String[] getContent() {
+		return content;
+	}
+
+	public boolean hasText() throws SAXException {
+		return true;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLTextReaper.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLTextReaper.java
new file mode 100644
index 0000000..907ba12
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLTextReaper.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * SAX Content reader, returns the text content of any XML element.
+ * 
+ * @author Grahame
+ * @deprecated Typo (Reaper) and unused
+ */
+class XMLTextReaper implements ContentHandler {
+
+	private String text = "";
+	
+	/**
+	 * Reads a byte array stream of a piece of XML
+	 * in order to grab the text content of the elements. 
+	 * @param stream
+	 * @throws SAXException
+	 */
+	public void read(ByteArrayInputStream stream) throws SAXException {
+		org.xml.sax.XMLReader xml;
+		try {
+			xml = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+			xml.setFeature("http://xml.org/sax/features/namespaces", true);
+			xml.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+			xml.setContentHandler(this);
+			xml.parse(new InputSource(stream));
+		} catch (Exception e) {
+			throw new SAXException(e);
+		}
+	}
+	
+	/**
+	 * Returns the text content of the element.
+	 * @return the text content of the element
+	 */
+	public String getText() {
+		return text;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+	 */
+	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
+		// taken out the extra space because it caused problems when handling long annotation content
+//		text = text + " " + new String(arg0, arg1, arg2);
+		text = text + new String(arg0, arg1, arg2);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endDocument()
+	 */
+	public void endDocument() throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void endElement(String arg0, String arg1, String arg2) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+	 */
+	public void endPrefixMapping(String arg0) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+	 */
+	public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
+	 */
+	public void processingInstruction(String arg0, String arg1) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
+	 */
+	public void setDocumentLocator(Locator arg0) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
+	 */
+	public void skippedEntity(String arg0) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startDocument()
+	 */
+	public void startDocument() throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+	 */
+	public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
+	 */
+	public void startPrefixMapping(String arg0, String arg1) throws SAXException {
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriter.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriter.java
new file mode 100644
index 0000000..7f44294
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriter.java
@@ -0,0 +1,780 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.uomo.xml.IXMLWriter;
+import org.eclipse.uomo.xml.XMLUtil;
+
+/**
+ * XML Writer class.
+ */
+public class XMLWriter extends OutputStreamWriter implements IXMLWriter {
+
+	private boolean xmlHeader = true;
+	private String charset;
+	private boolean prettyBase;
+	private boolean prettyHeader;
+	private boolean pendingClose;
+	private boolean pendingOpen;
+	private String pendingComment;
+	private int lineType = LINE_UNIX;
+	private OutputStream stream;
+	private boolean started = false;
+	private String[] specialAttributeNames = new String[] {"id", "name" };
+	private boolean sortAttributes;
+	private int attributeLineWrap;
+	
+	public final static int LINE_UNIX = 0;
+	public final static int LINE_WINDOWS = 1;
+
+	public XMLWriter(OutputStream stream, String charset) throws UnsupportedEncodingException {
+		super(stream, charset);
+		this.stream = stream;
+		this.charset = charset;
+	}
+
+	protected boolean condition(boolean bTest, String message) throws IOException {
+		if (!bTest)
+			throw new IOException(message);
+		return bTest;
+	}
+
+	// -- writing context ------------------------------------------------
+
+
+	
+	/**
+	 * Returns the encoding.
+	 * 
+	 * @param charset
+	 * @return encoding
+	 * @throws IOException
+	 */
+	public static String getXMLCharsetName(String charset) throws IOException {
+		if (charset == null || charset.equals(""))
+			return "UTF-8";
+		else if (charset.equals("US-ASCII"))
+			return "UTF-8";
+		else if (XMLUtil.charSetImpliesAscii(charset))
+			return "ISO-8859-1";
+		else if (charset.equals("UTF-8"))
+			return "UTF-8";
+		else if (charset.equals("UTF-16") || charset.equals("UTF-16BE") || charset.equals("UTF-16LE"))
+			return "UTF-16";
+		else 
+			throw new IOException("Unknown charset encoding "+charset);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#start()
+	 */
+	public void start() throws IOException {
+		condition(!started, "attempt to start after starting");
+		levels.clear();
+		attributes = null;
+		try {
+			if (xmlHeader) {
+				write("<?xml version=\"1.0\" encoding=\""+getXMLCharsetName(charset)+"\"?>");
+				if (prettyBase || prettyHeader)
+					write(lineType == LINE_UNIX ? "\n" : "\r\n");
+			}
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			throw new IOException(e.getMessage());
+		}
+		started = true;
+	}
+
+	private void checkStarted () throws IOException {
+		condition(started, "not started");
+	}
+
+	private void checkInElement() throws IOException {
+		condition(levels.size() > 0, "not in an element");
+	}
+
+	// -- attributes ----------------------------------------------------
+
+	private String[][] attributes;
+	
+	private void addAttribute(String name, String value) throws IOException {
+		addAttribute(name, value, false);
+	}
+
+	private void addAttribute(String name, String value, boolean noLines) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+
+		newLevelIfRequired();
+		value = XMLUtil.escapeXML(value, charset, noLines);
+
+		if (attributes == null) 
+			attributes = new String[][] {{name, value}};
+		else {
+			String[][] newattr = new String[attributes.length+1][];
+			for (int i = 0; i < attributes.length; i++) {
+				condition(!attributes[i][0].equals(name), "attempt to define attribute with name "+name+" more than once");
+				newattr[i] = attributes[i];
+			}
+			attributes = newattr;
+			attributes[attributes.length-1] = new String[] {name, value};
+		}
+	}
+
+	protected String getAttribute(String name) {
+		if (attributes != null) {
+			for (int i = 0; i < attributes.length; i++) {
+				if (attributes[i][0].equals(name)) {
+					return attributes[i][1];
+				}
+			}			
+		}
+		return null;
+	}
+	
+	protected void setAttribute(String name, String value) throws IOException {
+		newLevelIfRequired();
+		if (attributes == null) 
+			addAttribute(name, value, false);
+		else {
+			for (int i = 0; i < attributes.length; i++) {
+				if (attributes[i][0].equals(name)) {
+					attributes[i][1] = XMLUtil.escapeXML(value, charset, false);
+					return;
+				}
+			}
+			addAttribute(name, value);
+		}
+	}
+
+	protected void commitAttributes() throws IOException {
+		
+	}
+
+	
+	private boolean nameIsSpecial(String name) {
+		for (int i = 0; i < specialAttributeNames.length; i++) {
+			String n = specialAttributeNames[i];
+			if (n.equalsIgnoreCase(name))
+				return true;
+		}
+		return false;
+	}
+	
+	private void writeAttributes(int col) throws IOException {
+		commitAttributes();
+		if (attributes != null && sortAttributes)
+			sortAttributes();	
+		int c = col;
+		c = writeAttributeSet(true, c, col);
+		writeAttributeSet(false, c, col);
+		attributes = null;
+	}
+
+
+	private void sortAttributes() {
+		// bubble sort - look, it's easy
+		for (int i = 0; i < attributes.length - 1; i++) {
+			for (int j = 0; j < attributes.length - 1; j++) {
+				if (String.CASE_INSENSITIVE_ORDER.compare(attributes[j][0], attributes[j+1][0]) < 0) {
+					String[] t = attributes[j];
+					attributes[j] = attributes[j+1];
+					attributes[j+1] = t;
+				}
+			}
+		}
+		
+	}
+
+
+	private int writeAttributeSet(boolean special, int col, int wrap) throws IOException {
+		// first pass: name, id
+		if (attributes != null) {
+			for (int i=0; i < attributes.length; i++) {
+				String[] element = attributes[i];
+				if (nameIsSpecial(element[0]) == special) {
+					col = col + element[0].length()+element[1].length() + 4;
+					if (isPretty() && attributeLineWrap > 0 && col > attributeLineWrap && col > wrap) {
+						write(lineType == LINE_UNIX ? "\n" : "\r\n");
+						for (int j = 0; j < wrap; j++)
+							write(" ");
+						col = wrap;
+					}
+					write(' ');
+					write(element[0]);
+					write("=\"");
+					if (element[1] != null)
+						write(element[1]);
+					write("\"");
+				}
+			}
+		}
+		return col;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String, boolean)
+	 */
+	public void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || value != null && !value.equals(""))
+			attribute(namespace, name, value);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void attribute(String namespace, String name, String value) throws IOException {
+
+		checkStarted();
+		if (namespace == null || namespace.equals("")) 
+			addAttribute(name, value);
+		else
+			addAttribute(getNSAbbreviation(namespace)+name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String, boolean)
+	 */
+	public void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || value != null && !value.equals(""))
+			attribute(name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attribute(java.lang.String, java.lang.String)
+	 */
+	public void attribute(String name, String value) throws IOException {
+		checkStarted();
+		addAttribute(name, value);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#attributeNoLines(java.lang.String, java.lang.String)
+	 */
+	public void attributeNoLines(String name, String value) throws IOException {
+		checkStarted();
+		addAttribute(name, value, true);
+	}
+
+	// -- levels -------------------------------------------------
+
+	private XMLWriterStateStack levels = new XMLWriterStateStack();
+
+	private void newLevelIfRequired() throws IOException {
+		if (!pendingOpen) {
+			if (!levels.empty())
+				levels.current().seeChild();
+			XMLWriterState level = new XMLWriterState();
+			level.setPretty(isPretty());
+			levels.push(level);
+			pendingOpen = true;
+		}
+	}
+
+	// -- namespaces ---------------------------------------------
+
+
+	private void defineNamespace(String namespace, String abbrev) throws IOException {
+		checkStarted();
+		if (namespace != null && !namespace.equals("")) {
+			if (abbrev.equals(""))
+				abbrev = null;
+
+			newLevelIfRequired();
+
+			levels.current().addNamespaceDefn(namespace, abbrev);
+			if (abbrev == null)
+				addAttribute("xmlns", namespace);
+			else
+				addAttribute("xmlns:"+abbrev, namespace);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#findByNamespace(java.lang.String)
+	 */
+	public XMLNamespace findByNamespace(String namespace) {
+		for (int i = levels.size() - 1; i >= 0; i--) {
+			XMLNamespace ns = levels.item(i).getDefnByNamespace(namespace);
+			if (ns != null)
+				return ns;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespaceDefined(java.lang.String)
+	 */
+	public boolean namespaceDefined(String namespace) {
+		return namespace == null || namespace.equals("") || findByNamespace(namespace) != null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#findByAbbreviation(java.lang.String)
+	 */
+	public XMLNamespace findByAbbreviation(String abbreviation) {
+		for (int i = levels.size() - 1; i >= 0; i--) {
+			XMLNamespace ns = levels.item(i).getDefnByAbbreviation(abbreviation);
+			if (ns != null)
+				return ns;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#abbreviationDefined(java.lang.String)
+	 */
+	public boolean abbreviationDefined(String abbreviation) {
+		return findByAbbreviation(abbreviation) != null;
+	}
+
+	protected XMLNamespace findDefaultNamespace() {
+		for (int i = levels.size() - 1; i >= 0; i--) {
+			XMLNamespace ns = levels.item(i).getDefaultNamespace();
+			if (ns != null)
+				return ns;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#getDefaultNamespace()
+	 */
+	public String getDefaultNamespace() {
+		XMLNamespace ns = findDefaultNamespace();
+		if (ns == null)
+			return null;
+		else
+			return ns.getNamespace();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespace(java.lang.String)
+	 */
+	public void namespace(String namespace) throws IOException {
+		if (!namespaceDefined(namespace)) {
+			int index = 0;
+			while (abbreviationDefined("ns"+Integer.toString(index))) 
+				index++;
+			defineNamespace(namespace, "ns"+Integer.toString(index));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#defaultNamespace(java.lang.String)
+	 * 
+	 * Replace defaultNamespace()
+	 */
+	public void setDefaultNamespace(String namespace) throws IOException {
+		if ((namespace == null && getDefaultNamespace() != null) ||
+				(namespace != null && !namespace.equals(getDefaultNamespace())))
+			defineNamespace(namespace, "");			
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#namespace(java.lang.String, java.lang.String)
+	 */
+	public void namespace(String namespace, String abbreviation) throws IOException {
+		XMLNamespace ns = findByAbbreviation(abbreviation);
+		if (ns == null || !ns.getNamespace().equals(namespace))
+			defineNamespace(namespace, abbreviation);
+	}
+
+
+	private String getNSAbbreviation(String namespace) throws IOException {
+		if ("http://www.w3.org/XML/1998/namespace".equals(namespace))
+			return "xml:";
+		
+		if (namespace == null || "".equals(namespace))
+			return "";
+		
+		XMLNamespace ns = findByNamespace(namespace);
+		if (ns == null)
+			throw new IOException("Namespace "+namespace+" is not defined");
+		else if (ns.getAbbreviation() == null)
+			return "";
+		else
+			return ns.getAbbreviation()+":";
+	}
+
+	// -- public API -----------------------------------------------------------
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#comment(java.lang.String, boolean)
+	 */
+	public void comment(String comment, boolean doPretty) throws IOException {
+		checkStarted();
+		if (pendingClose) { 
+			write('>');
+			writePendingComment();
+			pendingClose = false;
+		}
+		if (doPretty) {
+			writePretty();
+			if (isPretty()) {
+				for (int i = 0; i < levels.size(); i++)
+					write("  ");
+			}
+		}
+		if (levels.inComment())
+			write("<!-- "+comment+" -- >");
+		else
+			write("<!-- "+comment+" -->");
+		if (doPretty && !isPretty())
+			writePretty();
+	}
+
+
+	private void writePendingComment() throws IOException {
+		if (pendingComment != null) {
+			if (isPretty())
+				write("   ");
+			if (levels.inComment())
+				write("<!-- "+pendingComment+" -- >");
+			else
+				write("<!-- "+pendingComment+" -->");
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String, java.lang.String)
+	 */
+	public void open(String namespace, String name) throws IOException {
+		open(namespace, name, null);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void open(String namespace, String name, String comment) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		checkStarted();
+		if (pendingClose) { 
+			write('>');
+			writePendingComment();
+			pendingClose = false;
+		}
+
+		if (name == null) {
+			throw new IOException("name is null");
+		}
+		newLevelIfRequired();
+		levels.current().setName(name);
+		levels.current().setNamespace(namespace);
+		int col = writePretty();
+		write('<');
+		if (namespace == null) {
+			write(name);
+			col = col + name.length()+1;
+		} else {
+			String n = getNSAbbreviation(namespace)+name;
+			write(n);
+			col = col + n.length()+1;
+		}
+		writeAttributes(col);
+		pendingOpen = false;
+		pendingClose = true;
+		pendingComment = comment;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close(java.lang.String)
+	 */
+	public void close(String name) throws IOException {
+		checkStarted();
+		if (levels.empty())
+			throw new IOException("Unable to close null|"+name+", nothing to close");
+		if (levels.current().getNamespace() != null || !levels.current().getName().equals(name))
+			throw new IOException("Unable to close null|"+name+", found "+levels.current().getNamespace()+"|"+levels.current().getName());
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close(java.lang.String, java.lang.String)
+	 */
+	public void close(String namespace, String name) throws IOException {
+		checkStarted();
+		if (levels.empty())
+			throw new IOException("Unable to close "+namespace+"|"+name+", nothing to close");
+		if (!levels.current().getNamespace().equals(namespace) || !levels.current().getName().equals(name))
+			throw new IOException("Unable to close "+namespace+"|"+name+", found "+levels.current().getNamespace()+"|"+levels.current().getName());
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#closeToLevel(int)
+	 */
+	public void closeToLevel(int count) throws IOException {
+		while (levels.size() > count)
+			close();		
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#close()
+	 */
+	public void close() throws IOException {
+		checkStarted();
+		if (levels.empty()) {
+			super.close();
+		} else {
+			if (pendingClose) { 
+				write("/>");
+				writePendingComment();
+				pendingClose = false;
+			} else {
+				if (levels.current().hasChildren())
+					writePretty();
+				write("</");
+				if (levels.current().getNamespace() == null)
+					write(levels.current().getName());
+				else
+					write(getNSAbbreviation(levels.current().getNamespace())+levels.current().getName());
+				write('>');
+			}
+			levels.pop();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#open(java.lang.String)
+	 */
+	public void open(String name) throws IOException {
+		open(null, name);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, boolean)
+	 */
+	public void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || content != null && !content.equals(""))
+			element(namespace, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void element(String namespace, String name, String content, String comment) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		open(namespace, name, comment);
+		text(content);
+		close();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void element(String namespace, String name, String content) throws IOException {
+		if (!XMLUtil.isNMToken(name))
+			throw new IOException("XML name "+name+" is not valid");
+		open(namespace, name);
+		text(content);
+		close();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String, boolean)
+	 */
+	public void element(String name, String content, boolean onlyIfNotEmpty) throws IOException {
+		if (!onlyIfNotEmpty || content != null && !content.equals(""))
+			element(null, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#element(java.lang.String, java.lang.String)
+	 */
+	public void element(String name, String content) throws IOException {
+		element(null, name, content);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#text(java.lang.String)
+	 */
+	public void text(String content) throws IOException {
+		text(content, false);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#text(java.lang.String, boolean)
+	 * 
+	 * Replace escapeText()
+	 */
+	public void text(String content, boolean dontEscape) throws IOException {
+		checkInElement();
+		if (content != null) {
+			if (pendingClose) { 
+				write(">");
+				writePendingComment();
+				pendingClose = false;
+			}
+			if (dontEscape)
+				write(content);
+			else
+				write(XMLUtil.escapeXML(content, charset, false));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#cData(java.lang.String)
+	 */
+	public void cData(String text) throws IOException {
+		text("<![CDATA["+text+"]]>");		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#writeBytes(byte[])
+	 */
+	public void writeBytes(byte[] bytes) throws IOException {
+		checkInElement();
+		if (pendingClose) { 
+			write(">");
+			writePendingComment();
+			pendingClose = false;
+		}
+		flush();
+		stream.write(bytes);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#isPretty()
+	 */
+	public boolean isPretty() throws IOException {
+		return (levels == null || levels.empty()) ? prettyBase : levels.current().isPretty();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#setPretty(boolean)
+	 */
+	public void setPretty(boolean pretty) throws IOException {
+		if (levels == null || levels.empty())
+			this.prettyBase = pretty;
+		else 
+			levels.current().setPretty(pretty);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#startCommentBlock()
+	 */
+	public void startCommentBlock() throws IOException {
+		if (levels.inComment())
+			throw new IOException("cannot nest comments");
+		levels.current().setInComment(true);
+		if (isPretty())
+			writePretty();
+		write("<!--");
+		if (isPretty())
+			writePretty();		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ohf.utilities.xml.IXMLWriter#endCommentBlock()
+	 */
+	public void endCommentBlock() throws IOException {
+		if (!levels.inComment())
+			throw new IOException("cannot close a comment block when it is open");
+		if (!levels.current().isInComment())
+			throw new IOException("cannot close a comment block when it is open");
+		if (isPretty())
+			writePretty();
+		write("-->");
+		if (isPretty())
+			writePretty();		
+		levels.current().setInComment(false);
+	}
+
+	public boolean isSortAttributes() {
+		return sortAttributes;
+	}
+
+	public void setSortAttributes(boolean sortAttributes) {
+		this.sortAttributes = sortAttributes;
+	}
+
+
+	public boolean isPrettyHeader() {
+		return prettyHeader;
+	}
+
+	public void setPrettyHeader(boolean pretty) {
+		this.prettyHeader = pretty;
+	}
+
+	public int writePretty() throws IOException {
+		return writePretty(true);
+	}
+	
+	public int writePretty(boolean eoln) throws IOException {
+		if (isPretty()) {
+			if (eoln)
+				write(lineType == LINE_UNIX ? "\n" : "\r\n");
+			for (int i = 0; i < levels.size() - 1; i++)
+				write("  ");
+			return (levels.size() - 1) * 2;
+		} else
+			return 0;
+	}
+
+	public int getLineType() {
+		return lineType;
+	}
+
+	public void setLineType(int lineType) {
+		this.lineType = lineType;
+	}
+
+	public boolean isXmlHeader() {
+		return xmlHeader;
+	}
+
+	public void setXmlHeader(boolean xmlHeader) {
+		this.xmlHeader = xmlHeader;
+	}
+
+	public String[] getSpecialAttributeNames() {
+		return specialAttributeNames;
+	}
+
+	public void setSpecialAttributeNames(String[] specialAttributeNames) {
+		this.specialAttributeNames = specialAttributeNames;
+	}
+
+	public int getAttributeLineWrap() {
+		return attributeLineWrap;
+	}
+
+	public void setAttributeLineWrap(int attributeLineWrap) {
+		this.attributeLineWrap = attributeLineWrap;
+	}
+
+	public void escapedText(String content) throws IOException {
+		text("");
+		int i = content.length();
+		if (isPretty())
+		  while (i > 0 && (content.charAt(i-1) == '\r' || content.charAt(i-1) == '\n'))
+			 i--;
+		write(content.substring(0, i));
+	}
+	
+	
+}
+
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterParser.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterParser.java
new file mode 100644
index 0000000..3e64a59
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterParser.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+
+import org.eclipse.uomo.xml.XMLObjectParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class XMLWriterParser extends XMLObjectParser {
+
+	XMLWriter writer;
+	
+	public XMLWriterParser(XMLWriter writer) {
+		super();
+		this.writer = writer;
+	}
+
+	public void start(String namespace, String name, String defaultNamespace, Attributes attributes) throws SAXException {
+		try {
+			writer.start();
+			startElement(namespace, name, defaultNamespace, attributes);
+		} catch (IOException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	public XMLObjectParser startElement(String namespace, String name, String defaultNamespace, Attributes attributes) throws SAXException {
+		try {
+			for (int i = 0; i < attributes.getLength(); i++) {
+				writer.namespace(attributes.getURI(i));
+				writer.attribute(attributes.getURI(i), attributes.getLocalName(i), attributes.getValue(i));
+			}
+			writer.namespace(namespace);
+			writer.open(namespace, name);
+		} catch (Exception e) {
+			throw new SAXException(e);
+		}
+		return null;
+	}
+
+	public void endChild(XMLObjectParser child) throws SAXException {
+		try {
+			writer.close();
+		} catch (Exception e) {
+			throw new SAXException(e);
+		}
+	}
+
+	public void endElement(String namespace, String name) throws SAXException {
+		try {
+			writer.close();
+			writer.flush();
+		} catch (Exception e) {
+			throw new SAXException(e);
+		}
+	}
+
+	public void findText(char[] ch, int start, int length, boolean whitespace) throws SAXException {
+		try {
+			if (!whitespace)
+				writer.text(String.valueOf(ch, start, length));
+		} catch (IOException e) {
+			throw new SAXException(e);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterState.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterState.java
new file mode 100644
index 0000000..01f1fd0
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterState.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+
+
+class XMLWriterState {
+
+	private String name;
+	private String namespace;
+	private boolean children;
+	private boolean inComment;
+	private boolean pretty;
+	
+	private XMLNamespace[] namespaceDefns = null;
+	
+	public void addNamespaceDefn(String namespace, String abbrev) throws IOException {
+		XMLNamespace ns;
+		ns = getDefnByAbbreviation(abbrev);
+		if (ns != null)
+			throw new IOException("duplicate namespace declaration on \""+abbrev+"\"");
+		ns = new XMLNamespace(namespace, abbrev);
+		if (namespaceDefns == null)
+			namespaceDefns = new XMLNamespace[] {ns};
+		else {
+			XMLNamespace[] newns = new XMLNamespace[namespaceDefns.length + 1];
+			for (int i = 0; i < namespaceDefns.length; i++) {
+				newns[i] = namespaceDefns[i];
+			}
+			namespaceDefns = newns;
+			namespaceDefns[namespaceDefns.length-1] = ns;			
+		}
+	}
+
+	public XMLNamespace getDefnByNamespace(String namespace) {
+		if (namespaceDefns == null)
+			return null;
+		for (int  i = 0; i < namespaceDefns.length; i++) {
+			XMLNamespace element = namespaceDefns[i];
+			if (element.getNamespace().equals(namespace))
+				return element;
+		}
+		return null;
+	}
+
+	public XMLNamespace getDefnByAbbreviation(String abbreviation) {
+		if (namespaceDefns == null)
+			return null;
+		for (int  i = 0; i < namespaceDefns.length; i++) {
+			XMLNamespace element = namespaceDefns[i];
+			if (element.getAbbreviation() != null && element.getAbbreviation().equals(abbreviation))
+				return element;
+		}
+		return null;
+	}
+
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * @return the namespace
+	 */
+	public String getNamespace() {
+		return namespace;
+	}
+
+	/**
+	 * @param namespace the namespace to set
+	 */
+	public void setNamespace(String namespace) {
+		this.namespace = namespace;
+	}
+
+	/**
+	 * @return the children
+	 */
+	public boolean hasChildren() {
+		return children;
+	}
+
+	/**
+	 * @param children the children to set
+	 */
+	public void seeChild() {
+		this.children = true;
+	}
+
+	public XMLNamespace getDefaultNamespace() {
+		if (namespaceDefns == null)
+			return null;
+		for (int  i = 0; i < namespaceDefns.length; i++) {
+			XMLNamespace element = namespaceDefns[i];
+			if (element.getAbbreviation() == null)
+				return element;
+		}
+		return null;
+	}
+
+	/**
+	 * @return the inComment
+	 */
+	public boolean isInComment() {
+		return inComment;
+	}
+
+	/**
+	 * @param inComment the inComment to set
+	 */
+	public void setInComment(boolean inComment) {
+		this.inComment = inComment;
+	}
+
+	/**
+	 * @return the pretty
+	 */
+	public boolean isPretty() {
+		return pretty;
+	}
+
+	/**
+	 * @param pretty the pretty to set
+	 */
+	public void setPretty(boolean pretty) {
+		this.pretty = pretty;
+	}
+
+	
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterStateStack.java b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterStateStack.java
new file mode 100644
index 0000000..c3c90f1
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/java/org/eclipse/uomo/xml/impl/XMLWriterStateStack.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Crown Copyright (c) 2006, 2007, Copyright (c) 2006, 2007 Jiva Medical.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    Jiva Medical - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.uomo.xml.impl;
+
+import java.io.IOException;
+import java.util.Vector;
+
+
+class XMLWriterStateStack {
+
+	private Vector<XMLWriterState> items = new Vector<XMLWriterState>();
+
+	public int size(){
+		return items.size();
+	}
+	
+	public boolean empty(){
+		return items.size() == 0;
+	}
+	
+	public XMLWriterState current() throws IOException {
+		if (empty())
+			throw new IOException("stack is empty trying to get current");
+		return (XMLWriterState)items.get(items.size() - 1);
+	}
+	
+	
+	public void push(XMLWriterState element) {
+		items.add(element);		
+	}
+		
+	public void clear () {
+		if (items != null)
+		  items.clear();
+	}
+
+	public void pop() throws IOException {
+		if (empty())
+			throw new IOException("stack is empty trying to pop");
+		if (current().isInComment())
+			throw new IOException("Must close a comment sequence in the element in which it was started");
+		
+		items.remove(items.size() - 1);		
+	}
+
+	public XMLWriterState item(int index) {
+		return (XMLWriterState)items.get(index);
+	}
+
+	public boolean inComment() {
+		for (int i = 0; i < items.size(); i++) {
+			if (((XMLWriterState)items.get(i)).isInComment())
+				return true;					
+		}
+		return false;
+	}
+
+}
diff --git a/bundles/org.eclipse.uomo.xml/src/main/resources/org/eclipse/uomo/xml/messages.properties b/bundles/org.eclipse.uomo.xml/src/main/resources/org/eclipse/uomo/xml/messages.properties
new file mode 100644
index 0000000..408b595
--- /dev/null
+++ b/bundles/org.eclipse.uomo.xml/src/main/resources/org/eclipse/uomo/xml/messages.properties
@@ -0,0 +1 @@
+XMLObjectParsers_stackUnderflow=stack underflow
diff --git a/bundles/pom.xml b/bundles/pom.xml
new file mode 100644
index 0000000..0876ffb
--- /dev/null
+++ b/bundles/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+  <artifactId>org.eclipse.uomo.bundles</artifactId>
+  <name>Eclipse UOMo Bundles</name>
+  <packaging>pom</packaging>
+  <modules>
+  	<module>org.eclipse.uomo.core</module>
+  	<module>org.eclipse.uomo.core.tests</module>
+  	<module>org.eclipse.uomo.units</module>
+  	<module>org.eclipse.uomo.units.tests</module>
+  	<module>org.eclipse.uomo.xml</module>
+  	<module>org.eclipse.uomo.xml.tests</module>
+  	<module>org.eclipse.uomo.util</module>
+  	<module>org.eclipse.uomo.util.tests</module>
+  	<module>org.eclipse.uomo.ucum</module>
+  	<module>org.eclipse.uomo.ucum.tests</module>
+  	<module>org.eclipse.uomo.business</module>
+  	<module>org.eclipse.uomo.ui</module>
+  	<!-- <module>org.eclipse.uomo.business.tests</module>-->
+  </modules>
+</project>
\ No newline at end of file
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..834befa
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,3 @@
+/src
+/.settings
+/target
diff --git a/examples/.project b/examples/.project
new file mode 100644
index 0000000..68aebbb
--- /dev/null
+++ b/examples/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>examples</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/business/.project b/examples/business/.project
new file mode 100644
index 0000000..152554a
--- /dev/null
+++ b/examples/business/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.examples.business</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/.classpath b/examples/business/org.eclipse.uomo.examples.business.console/.classpath
new file mode 100644
index 0000000..73f6cfa
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/.classpath
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+	<classpathentry kind="lib" path="lib/icu4j-50_1_1.jar"/>
+</classpath>
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/.project b/examples/business/org.eclipse.uomo.examples.business.console/.project
new file mode 100644
index 0000000..3abc28d
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.examples.business.console</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/lib/icu4j-50_1_1.jar b/examples/business/org.eclipse.uomo.examples.business.console/lib/icu4j-50_1_1.jar
new file mode 100644
index 0000000..4994a5c
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/lib/icu4j-50_1_1.jar
Binary files differ
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/pom.xml b/examples/business/org.eclipse.uomo.examples.business.console/pom.xml
new file mode 100644
index 0000000..a1be7e4
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/pom.xml
@@ -0,0 +1,57 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.uomo.examples.business</groupId>
+    <artifactId>org.eclipse.uomo.examples.business</artifactId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>org.eclipse.uomo.examples.business.console</artifactId>
+  
+  	<dependencies>
+		<dependency>
+            <groupId>org.unitsofmeasurement</groupId>
+            <artifactId>unit-api</artifactId>
+            <version>0.6.1</version>
+		</dependency>	
+        <dependency>
+        	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        	<artifactId>org.eclipse.uomo.units</artifactId>
+        	<version>${project.version}</version>
+        </dependency>	
+         <dependency>
+       		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        	<artifactId>org.eclipse.uomo.business</artifactId>
+        	<version>${project.version}</version>
+        </dependency>
+        
+		<dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <version>1.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+       		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        	<artifactId>org.eclipse.uomo.core</artifactId>
+        	<version>${project.version}</version>
+        </dependency>
+<!--         <dependency> -->
+<!--         	<groupId>com.ibm.icu</groupId> -->
+<!--         	<artifactId>icu4j</artifactId> -->
+<!--         	<version>50.1.1</version> -->
+<!--         </dependency> -->
+		<dependency>
+			<groupId>org.eclipse</groupId>
+			<artifactId>osgi</artifactId>
+			<version>3.5.0.v20090520</version>
+		</dependency>
+	</dependencies>
+  	<name>UOMo Business Console Examples</name>
+</project>
\ No newline at end of file
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/etc/MoneyDemo1.xlsx b/examples/business/org.eclipse.uomo.examples.business.console/src/etc/MoneyDemo1.xlsx
new file mode 100644
index 0000000..1f8ad69
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/etc/MoneyDemo1.xlsx
Binary files differ
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/internal/DemoMessages.java b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/internal/DemoMessages.java
new file mode 100644
index 0000000..e3881e0
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/internal/DemoMessages.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.business.console.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class DemoMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.uomo.business.money.demomessages"; //$NON-NLS-1$
+	public static String MoneyDemo_Car_mileage;
+	public static String MoneyDemo_Gas_price;
+	public static String MoneyDemo_Trip_cost;
+	public static String MoneyDemo_Trip_distance;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, DemoMessages.class);
+	}
+
+	private DemoMessages() {
+	}
+}
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/MoneyDemo.java b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/MoneyDemo.java
new file mode 100644
index 0000000..9bfc764
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/MoneyDemo.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.business.console.money;
+
+//Constants (Java 5 static import)
+import static org.eclipse.uomo.business.money.MoneyUnit.EUR;
+import static org.eclipse.uomo.business.money.MoneyUnit.USD;
+
+import org.eclipse.uomo.business.internal.CurrencyUnit;
+import org.eclipse.uomo.business.internal.MonetaryAmount;
+import org.eclipse.uomo.business.money.MoneyAmount;
+import org.eclipse.uomo.business.money.MoneyConverter;
+import org.eclipse.uomo.business.money.MoneyUnit;
+
+/**
+ * @author Werner Keil
+ * @version 0.9.8, $Date: 2013-05-20 $
+ */
+public class MoneyDemo {
+
+	/**
+	 * @param args
+	 *            The application arguments if required.
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static void main(String[] args) {
+		// /////////////////////////////////////////////////////////////////////
+		// Calculates the cost of a car trip in Europe for an American tourist.
+		// /////////////////////////////////////////////////////////////////////
+
+		@SuppressWarnings("unused")
+		MoneyConverter converter = new MoneyConverter(USD, EUR, 1.4);
+		CurrencyUnit currency = MoneyUnit.of("CHF");
+		MonetaryAmount money = MoneyAmount.of(100, currency);
+		
+		System.out.println(money);
+//		System.out.println(money.getCurrency());
+		System.out.println(converter.convert(34.6d));
+	}
+}
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/TripCost.java b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/TripCost.java
new file mode 100644
index 0000000..d642a70
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/java/org/eclipse/uomo/examples/business/console/money/TripCost.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.business.console.money;
+
+// Constants (Java 5 static import)
+import static org.eclipse.uomo.units.impl.system.USCustomary.GALLON_LIQUID;
+import static org.eclipse.uomo.units.impl.system.USCustomary.LITER;
+import static org.eclipse.uomo.units.impl.system.USCustomary.MILE;
+import static org.eclipse.uomo.units.SI.Prefix.KILO;
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.business.money.MonetaryUnits.INR;
+import static org.eclipse.uomo.business.money.MoneyUnit.EUR;
+import static org.eclipse.uomo.business.money.MoneyUnit.GBP;
+import static org.eclipse.uomo.business.money.MoneyUnit.USD;
+
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.UnitFormat;
+
+import org.eclipse.uomo.business.money.MoneyConverter;
+import org.eclipse.uomo.business.money.MoneyUnit;
+import org.eclipse.uomo.business.types.IMoney;
+import org.eclipse.uomo.examples.business.console.internal.DemoMessages;
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.QuantityAmount;
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+
+/**
+ * @author Werner Keil
+ * @version 0.9.2, 2013-05-20
+ */
+public class TripCost {
+  
+	
+	/**
+	 * @param args
+	 *            The application arguments if required.
+	 */
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static void main(String[] args) {
+		// /////////////////////////////////////////////////////////////////////
+		// Calculates the cost of a car trip in Europe for an American tourist.
+		// /////////////////////////////////////////////////////////////////////
+
+		@SuppressWarnings("unused")
+		MoneyConverter converter = new MoneyConverter(USD, EUR, 1.4);
+
+		// Calculates trip cost.
+		BaseAmount carMileage = new BaseAmount(20,
+				MILE.divide(GALLON_LIQUID)); // 20 mi/gal.
+		IMeasure<IMoney> gazPrice = new BaseAmount(1.2, EUR.divide(LITER));
+		// // 1.2 EUR/L
+		LengthAmount tripDistance = new LengthAmount(400, KILO(METRE)); // 400 km
+//		IMeasure<Length> tripDistance2 = new LengthAmount(400, KILO(METRE));
+//		LengthAmount tripDistance = new LengthAmount(4, (Unit<Length>) LAKH(METRE)); // 400 km 
+		
+		
+		// km
+		IMeasure<?> tripCost =  tripDistance.divide(
+				carMileage).multiply(gazPrice); // .to(USD);
+
+		// Display trip.
+		System.out.println(DemoMessages.MoneyDemo_Car_mileage + carMileage);
+		System.out.println(DemoMessages.MoneyDemo_Trip_distance + tripDistance);
+
+		// Display cost.
+		System.out.print(DemoMessages.MoneyDemo_Gas_price);
+		System.out.println(gazPrice); // FIXME format for CurrencyConverter
+		// UFormat format = MeasureFormat.getCurrencyFormat();
+		// System.out.println(format.format(gazPrice));
+		// MoneyAmount mo = MoneyAmount.valueOf(100, EUR);
+		// System.out.println(currFormat.format(mo));
+		System.out.println(DemoMessages.MoneyDemo_Trip_cost + tripCost); // + " (" +
+
+		System.out.println("In USD: " + gazPrice.doubleValue(USD));
+		System.out.println("Trip Cost"
+				+ ((QuantityAmount) tripCost).to(USD)); //$NON-NLS-1$
+		//System.out.println(DemoMessages.MoneyDemo_Trip_cost + tripCost.to(USD));
+//		System.out.println(Messages.MoneyDemo_Trip_cost
+//				+ ((BaseAmount) tripCost).to(EUR)); //$NON-NLS-1$
+		// System.out.println("Trip cost = " + tripCost + " (" +
+		// tripCost.to(GBP) + ")");
+		// System.out.println("Trip cost = " + tripCost + " (" +
+		// tripCost.to(INR) + ")");
+	}
+
+	/*
+	 1.00 CZK=0.0640254 USD
+	Czech Republic Koruny 	  	United States Dollars
+	1 CZK = 0.0640254 USD 	  	1 USD = 15.6188 CZK
+	 */
+}
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages.properties b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages.properties
new file mode 100644
index 0000000..5312dd3
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages.properties
@@ -0,0 +1,4 @@
+MoneyDemo_Car_mileage=Car  mileage  = 
+MoneyDemo_Gas_price=Gas  price   \= 
+MoneyDemo_Trip_cost=Trip cost = 
+MoneyDemo_Trip_distance=Trip distance = 
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages_de.properties b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages_de.properties
new file mode 100644
index 0000000..db3d6a6
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/demomessages_de.properties
@@ -0,0 +1,9 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+
+MoneyDemo_Car_mileage = Reichweite = 
+
+MoneyDemo_Gas_price = Spritpreis = 
+
+MoneyDemo_Trip_cost = Fahrtkosten\= 
+
+MoneyDemo_Trip_distance = Strecke    \= 
diff --git a/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/package-info.java b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/package-info.java
new file mode 100644
index 0000000..d68c549
--- /dev/null
+++ b/examples/business/org.eclipse.uomo.examples.business.console/src/main/resources/org/eclipse/uomo/business/money/package-info.java
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+/**
+ * @author Werner Keil
+ *
+ */
+package money;
\ No newline at end of file
diff --git a/examples/business/pom.xml b/examples/business/pom.xml
new file mode 100644
index 0000000..93eecfd
--- /dev/null
+++ b/examples/business/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.examples</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.examples.business</artifactId>
+	<packaging>pom</packaging>
+	<name>Eclipse UOMo Business Examples</name>
+	<modules>
+    <module>org.eclipse.uomo.examples.business.console</module>
+	</modules>
+	<!-- ==================================================== -->
+    <!-- Repositories. This is where Maven looks for dependencies. 
+         The Maven repository is implicit and doesn't need 
+         to be specified. -->
+    <!-- ==================================================== -->
+    <repositories>
+        <repository>
+            <id>maven-geotoolkit.org</id>
+            <name>GeoToolkit Repository for Maven</name>
+            <url>http://maven.geotoolkit.org/</url>
+        </repository>
+        
+        <repository>
+            <id>OpenL10n</id>
+            <name>Openl10.net</name>
+            <url>http://nexus.openl10n.net/content/groups/public/</url>
+        </repository>
+    </repositories>
+	
+    <groupId>org.eclipse.uomo.examples.business</groupId>
+</project>
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
new file mode 100644
index 0000000..9948431
--- /dev/null
+++ b/examples/pom.xml
@@ -0,0 +1,36 @@
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<parent>
+		<artifactId>org.eclipse.uomo</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.eclipse.uomo.examples</artifactId>
+	<packaging>pom</packaging>
+	<name>Eclipse UOMo Examples</name>
+	<build>
+	   <plugins>
+	        <!-- ======================================================= -->
+            <!-- Compilation -->
+            <!-- ======================================================= -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven.compilerPlugin.version}</version>
+                <configuration>
+					<source>${project.build.javaVersion}</source>
+					<target>${project.build.javaVersion}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+	</build>
+	<modules>
+	   <module>business</module>
+	   <module>units</module>
+	</modules>
+<!-- modules> <module>org.eclipse.uomo.test</module> </modules -->
+</project>
\ No newline at end of file
diff --git a/examples/units/.gitignore b/examples/units/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/examples/units/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/examples/units/.project b/examples/units/.project
new file mode 100644
index 0000000..ea8a7db
--- /dev/null
+++ b/examples/units/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.examples.units</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/.classpath b/examples/units/org.eclipse.uomo.examples.units.android/.classpath
new file mode 100644
index 0000000..7cec603
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/.classpath
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/.gitignore b/examples/units/org.eclipse.uomo.examples.units.android/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/.project b/examples/units/org.eclipse.uomo.examples.units.android/.project
new file mode 100644
index 0000000..be25aca
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>android-player-root</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/.classpath b/examples/units/org.eclipse.uomo.examples.units.android/player/.classpath
new file mode 100644
index 0000000..c13cb5f
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="src" output="bin/classes" path="gen">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="bin/classes" path="src/main/java"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/.gitignore b/examples/units/org.eclipse.uomo.examples.units.android/player/.gitignore
new file mode 100644
index 0000000..945bcb2
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/.gitignore
@@ -0,0 +1,3 @@
+/bin
+/gen
+/target
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/.project b/examples/units/org.eclipse.uomo.examples.units.android/player/.project
new file mode 100644
index 0000000..d976f9f
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/.project
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>player</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/AndroidManifest.xml b/examples/units/org.eclipse.uomo.examples.units.android/player/AndroidManifest.xml
new file mode 100644
index 0000000..8d5c1a8
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="org.org.eclipse.uomo.examples.units.android" android:versionCode="1" android:versionName="0.1.0.SNAPSHOT">
+
+  <application android:icon="@drawable/icon" android:label="@string/app_name">
+    <activity android:name=".HelloAndroidActivity">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+
+</manifest>
+
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/pom.xml b/examples/units/org.eclipse.uomo.examples.units.android/player/pom.xml
new file mode 100644
index 0000000..d486bab
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.examples.units.android</artifactId>
+		<groupId>org.eclipse.uomo.examples.units</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+	</parent>
+	<!-- from parent <groupId>org.mic.maven.web.android.archetype</groupId> -->
+	<artifactId>player</artifactId>
+	<!-- from parent <version>1.0-SNAPSHOT</version> -->
+	<!-- for plugin, currently fails, run manually with ADT 
+	 <packaging>apk</packaging -->
+	<packaging>pom</packaging>
+	<name>UOMo Units Android Example Player</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.google.android</groupId>
+			<artifactId>android</artifactId>
+			<version>2.2.1</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>com.jayway.maven.plugins.android.generation2</groupId>
+				<artifactId>android-maven-plugin</artifactId>
+				<version>3.0.0-alpha-14</version>
+				<configuration>
+					<androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
+					<assetsDirectory>${project.basedir}/assets</assetsDirectory>
+					<resourceDirectory>${project.basedir}/res</resourceDirectory>
+					<nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
+					<sdk>
+						<platform>8</platform>
+					</sdk>
+					<deleteConflictingFiles>true</deleteConflictingFiles>
+					<undeployBeforeDeploy>true</undeployBeforeDeploy>
+				</configuration>
+				<extensions>true</extensions>
+			</plugin>
+			<!-- from parent <plugin> <artifactId>maven-compiler-plugin</artifactId> 
+				<version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> 
+				</configuration> </plugin> -->
+		</plugins>
+	</build>
+</project>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/project.properties b/examples/units/org.eclipse.uomo.examples.units.android/player/project.properties
new file mode 100644
index 0000000..ea89160
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-hdpi/icon.png b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..afc1a0e
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-ldpi/icon.png b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..5a89924
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-mdpi/icon.png b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..7e079bb
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/res/layout/main.xml b/examples/units/org.eclipse.uomo.examples.units.android/player/res/layout/main.xml
new file mode 100644
index 0000000..09d2d1b
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/res/layout/main.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView  
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content" 
+    android:text="@string/hello"
+    />
+</LinearLayout>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/res/values/strings.xml b/examples/units/org.eclipse.uomo.examples.units.android/player/res/values/strings.xml
new file mode 100644
index 0000000..8862e88
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="hello">Hello player!</string>
+    <string name="app_name">player</string>
+</resources>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/player/src/main/java/org/org/eclipse/uomo/examples/units/android/HelloAndroidActivity.java b/examples/units/org.eclipse.uomo.examples.units.android/player/src/main/java/org/org/eclipse/uomo/examples/units/android/HelloAndroidActivity.java
new file mode 100644
index 0000000..251ec1a
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/player/src/main/java/org/org/eclipse/uomo/examples/units/android/HelloAndroidActivity.java
@@ -0,0 +1,29 @@
+package org.org.eclipse.uomo.examples.units.android;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.RelativeLayout;
+
+public class HelloAndroidActivity extends Activity {
+
+    private static String TAG = "player";
+
+    /**
+     * Called when the activity is first created.
+     * @param savedInstanceState If the activity is being re-initialized after 
+     * previously being shut down then this Bundle contains the data it most 
+     * recently supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it is null.</b>
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+		Log.i(TAG, "onCreate");
+		
+		RelativeLayout relativeLayout = new RelativeLayout(this);
+		
+        setContentView(relativeLayout);
+    }
+
+}
+
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/pom.xml b/examples/units/org.eclipse.uomo.examples.units.android/pom.xml
new file mode 100644
index 0000000..01e6501
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+        <artifactId>org.eclipse.uomo.examples.units</artifactId>
+        <groupId>org.eclipse.uomo.examples.units</groupId>
+        <version>0.6.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.examples.units.android</artifactId>
+	<packaging>pom</packaging>
+	<name>UOMo Units Android Examples</name>
+	<build>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<version>${maven.compilerPlugin.version}</version>
+					<configuration>
+						<source>${project.build.javaVersion}</source>
+						<target>${project.build.javaVersion}</target>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>3.8.1</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+  <modules>
+    <module>web</module>
+    <module>player</module>
+  </modules>
+</project>
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/.classpath b/examples/units/org.eclipse.uomo.examples.units.android/web/.classpath
new file mode 100644
index 0000000..d96e906
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/.classpath
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.jboss.ide.eclipse.as.core.server.runtime.runtimeTarget/JBoss 7.0 Runtime"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/.gitignore b/examples/units/org.eclipse.uomo.examples.units.android/web/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/.project b/examples/units/org.eclipse.uomo.examples.units.android/web/.project
new file mode 100644
index 0000000..eec3b2f
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/.project
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>web</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.jboss.tools.ws.jaxrs.metamodelBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+		<nature>org.jboss.tools.ws.jaxrs.nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/pom.xml b/examples/units/org.eclipse.uomo.examples.units.android/web/pom.xml
new file mode 100644
index 0000000..e0c907c
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.examples.units.android</artifactId>
+		<groupId>org.eclipse.uomo.examples.units</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+	</parent>
+	<!-- form parent <groupId>org.mic.maven.web.android.archetype</groupId> -->
+	<artifactId>web</artifactId>
+	<!-- form parent <version>1.0-SNAPSHOT</version> -->
+	<packaging>war</packaging>
+	<name>UOMo Units Android Example Webapp</name>
+	<build>
+		<finalName>android-web</finalName>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>javax</groupId>
+			<artifactId>javaee-web-api</artifactId>
+			<version>6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+			<artifactId>org.eclipse.uomo.units</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.unitsofmeasurement</groupId>
+			<artifactId>unit-api</artifactId>
+			<version>0.6.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.ibm.icu</groupId>
+			<artifactId>icu4j</artifactId>
+			<version>4.8.1.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+			<artifactId>org.eclipse.uomo.core</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse</groupId>
+			<artifactId>osgi</artifactId>
+			<version>3.5.0.v20090520</version>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/UnitConverterServlet.java b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/UnitConverterServlet.java
new file mode 100644
index 0000000..6cc3172
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/UnitConverterServlet.java
@@ -0,0 +1,79 @@
+package org.eclipse.uomo.examples.units.android.web;
+
+import static org.eclipse.uomo.units.SI.CELSIUS;
+import static org.eclipse.uomo.units.impl.system.USCustomary.FAHRENHEIT;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.uomo.units.*;
+import org.eclipse.uomo.units.impl.quantity.TemperatureAmount;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.quantity.Temperature;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * Servlet implementation class UnitConverterServlet
+ * @param <Q>
+ */
+public class UnitConverterServlet<Q extends Quantity<Q>> extends HttpServlet {
+	private static final long serialVersionUID = 1L;
+	private final QuantityAmount<Temperature> amount;
+	private UnitConverter converter;
+	
+    /**
+     * Default constructor. 
+     */
+    public UnitConverterServlet() {
+        amount = new TemperatureAmount(0, CELSIUS);
+    }
+
+	/**
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
+	 *      response)
+	 */
+	public void doGet(HttpServletRequest in, HttpServletResponse output)
+			throws ServletException, IOException {
+
+		output.setContentType("text/html");
+		PrintWriter out = output.getWriter();
+
+		out.println("<html><head><title>Temperature Conversion</title></head>");
+		out.println("<body>");
+		out.println("<h1> " + FAHRENHEIT + " to " + CELSIUS + " conversion</h1>");
+		if (in.getParameter("t_in") != null) {
+			String supplied_temp = in.getParameter("t_in");
+			double base_temp = -999;
+			TemperatureAmount base_temp_amt = null;
+			boolean valid = false;
+			try {
+				base_temp = Double.parseDouble(supplied_temp);
+				base_temp_amt = new TemperatureAmount(base_temp, FAHRENHEIT);
+				valid = true;
+			} catch (NumberFormatException e) {
+				out.println("<h4><font color=red>"
+						+ "Invalid Temperature Supplied</font></h4)<br>");
+			}
+			if (valid) {
+				out.println("<h4>Temperature " + base_temp_amt
+						//+ " "+ FAHRENHEIT 
+						+ " converts to "						
+						//+ ((((double) base_temp - 32.0d) / 9.0d) * 5.0d)
+						//+ " " + CELSIUS
+						+ base_temp_amt.to(CELSIUS) 
+						+ " </h4>");
+			}
+		}
+		out.println("<form>Enter " + FAHRENHEIT + ": ");
+		out.println("<input name=t_in>");
+		out.println("<input type=submit></form><br>");
+
+		out.println("<a href=index.jsp>Return to home page of this webapp</a><br><br>");
+		out.println("</body></html>");
+		out.close();
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/sandbox/Tempconv.java b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/sandbox/Tempconv.java
new file mode 100644
index 0000000..b77cebd
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/java/org/eclipse/uomo/examples/units/android/web/sandbox/Tempconv.java
@@ -0,0 +1,60 @@
+package org.eclipse.uomo.examples.units.android.web.sandbox;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Servlet implementation class Tempconv
+ */
+public class Tempconv extends HttpServlet {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
+	 *      response)
+	 */
+	public void doGet(HttpServletRequest in, HttpServletResponse output)
+			throws ServletException, IOException {
+
+		output.setContentType("text/html");
+		PrintWriter out = output.getWriter();
+
+		out.println("<html><head><title>Temperature Conversion</title></head>");
+		out.println("<body>");
+		out.println("<h1>Degrees F to degrees C conversion</h1>");
+		if (in.getParameter("t_in") != null) {
+			String supplied_temp = in.getParameter("t_in");
+			float base_temp = -999;
+			boolean valid = false;
+			try {
+				base_temp = Float.parseFloat(supplied_temp);
+				valid = true;
+			} catch (NumberFormatException e) {
+				out.println("<h4><font color=red>"
+						+ "Invalid Temperature Supplied</font></h4)<br>");
+			}
+			if (valid) {
+				out.println("<h4>Temperature " + base_temp
+						+ " deg f converts to "
+						+ ((((float) base_temp - 32.0f) / 9.0f) * 5.0f)
+						+ " deg celcius </h4>");
+			}
+		}
+		out.println("<form>Enter degrees F: ");
+		out.println("<input name=t_in>");
+		out.println("<input type=submit></form><br>");
+
+		out.println("<a href=index.jsp>Return to home page of this webapp</a><br><br>");
+		out.println("Initial contribution by Well House Consultants Ltd<br>");
+		out.println("web <a href=http://www.wellho.net>http://www.wellho.net</a><br>");
+		out.println("email <a href=mailto:info@wellho.net>info@wellho.net</a><br>");
+		out.println("</body></html>");
+		out.close();
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/WEB-INF/web.xml b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..28802c7
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,37 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>UOMo Units Android Example Web Application</display-name>
+  <servlet>
+  	<servlet-name>UnitConverterServlet</servlet-name>
+  	<display-name>UnitConverterServlet</display-name>
+  	<description>Unit Converter</description>
+  	<servlet-class>org.eclipse.uomo.examples.units.android.web.UnitConverterServlet</servlet-class>
+  	<init-param>
+  		<param-name>unit</param-name>
+  		<param-value></param-value>
+  		<description>Unit</description>
+  	</init-param>
+  	<init-param>
+  		<param-name>value</param-name>
+  		<param-value></param-value>
+  		<description>Value</description>
+  	</init-param>
+  </servlet>
+  <servlet>
+  	<servlet-name>Tempconv</servlet-name>
+  	<display-name>Tempconv</display-name>
+  	<description>Temperature Converter</description>
+  	<servlet-class>org.eclipse.uomo.examples.units.android.web.sandbox.Tempconv</servlet-class>
+  </servlet>
+  <servlet-mapping>
+  	<servlet-name>UnitConverterServlet</servlet-name>
+  	<url-pattern>/UnitConverter</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+  	<servlet-name>Tempconv</servlet-name>
+  	<url-pattern>/Tempconv</url-pattern>
+  </servlet-mapping>
+</web-app>
diff --git a/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/index.jsp b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/index.jsp
new file mode 100644
index 0000000..65a0530
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.android/web/src/main/webapp/index.jsp
@@ -0,0 +1,13 @@
+<%@ page import="org.unitsofmeasurement.quantity.*, org.eclipse.uomo.units.*, org.eclipse.uomo.units.impl.quantity.*" %>
+<html>
+<head>
+	<title>Eclipse UOMo</title>
+</head>
+<body>
+<h2>Hello UOMo!</h2>
+<%
+	QuantityAmount<Length> q = new LengthAmount(12, SI.METRE);
+%>
+<%= q %>
+</body>
+</html>
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/.classpath b/examples/units/org.eclipse.uomo.examples.units.console/.classpath
new file mode 100644
index 0000000..b422fcd
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/.classpath
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/.gitignore b/examples/units/org.eclipse.uomo.examples.units.console/.gitignore
new file mode 100644
index 0000000..e7da900
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/.gitignore
@@ -0,0 +1,3 @@
+/target
+/.settings
+/target
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/.project b/examples/units/org.eclipse.uomo.examples.units.console/.project
new file mode 100644
index 0000000..5b138e2
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/.project
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.examples.units.console</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/pom.xml b/examples/units/org.eclipse.uomo.examples.units.console/pom.xml
new file mode 100644
index 0000000..83db523
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/pom.xml
@@ -0,0 +1,94 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.examples.units</artifactId>
+		<groupId>org.eclipse.uomo.examples.units</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.examples.units.console</artifactId>
+	<name>UOMo Units Console Examples</name>
+	<dependencies>
+		<dependency>
+            <groupId>org.unitsofmeasurement</groupId>
+            <artifactId>unit-api</artifactId>
+            <version>0.6.1</version>
+		</dependency>	
+        <dependency>
+        	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        	<artifactId>org.eclipse.uomo.units</artifactId>
+        	<version>${project.version}</version>
+        </dependency>	
+		<dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <version>1.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+        	<artifactId>org.eclipse.uomo.core</artifactId>
+        	<version>${project.version}</version>       	
+        </dependency>
+<!--         <dependency> -->
+<!--         	<groupId>com.ibm.icu</groupId> -->
+<!--         	<artifactId>icu4j</artifactId> -->
+<!--         	<version>4.8.1.1</version> -->
+<!--         </dependency> -->
+		<dependency>
+			<groupId>org.eclipse</groupId>
+			<artifactId>osgi</artifactId>
+			<version>3.5.0.v20090520</version>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+			<artifactId>org.eclipse.uomo.util</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+	</dependencies>
+
+	<!-- ======================================================= -->
+	<!-- Build Settings -->
+	<!-- ======================================================= -->
+	<build>
+		<plugins>
+			<!-- ======================================================= -->
+			<!-- Compilation -->
+			<!-- ======================================================= -->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>${project.build.javaVersion}</source>
+					<target>${project.build.javaVersion}</target>
+					<encoding>${project.build.sourceEncoding}</encoding>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	
+	 <!-- ==================================================== -->
+    <!-- Repositories. This is where Maven looks for dependencies. The Maven 
+        repository is implicit and doesn't need to be specified. -->
+    <!-- ==================================================== -->
+    <repositories>
+        <repository>
+            <id>maven-geotoolkit.org</id>
+            <name>GeoToolkit Repository for Maven</name>
+            <url>http://maven.geotoolkit.org/</url>
+        </repository>
+        <repository>
+			<id>eclipse-central</id>
+			<name>Central Eclipse.org Nexus</name>
+			<url>http://maven.eclipse.org/nexus/content/groups/central/</url>
+		</repository>               
+    </repositories>
+</project>
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/Messages.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/Messages.java
new file mode 100644
index 0000000..d655783
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/Messages.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units;
+
+import org.eclipse.osgi.util.NLS;
+
+@Deprecated
+public class Messages extends NLS {
+	
+	private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+	public static String Planet_Radius;
+	public static String Planet_SurfaceGravity;
+	public static String Planet_Usage;
+	public static String Planet_SurfaceWeight;
+	public static String REP_100mR;
+	public static String REP_1R;
+	public static String REP_2dot5R;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/ConverterExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/ConverterExample.java
new file mode 100644
index 0000000..0f08d9b
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/ConverterExample.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2005, 2012, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console;
+
+import static org.eclipse.uomo.units.SI.*;
+import static org.eclipse.uomo.units.SI.Prefix.KILO;
+import static org.eclipse.uomo.units.impl.system.USCustomary.*;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+public class ConverterExample {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+	    // Conversion between units.
+		UnitConverter conv = KILO(METRE).getConverterTo(MILE);
+	    System.out.println(conv.convert(10.0));
+	    // Retrieval of the system unit (identifies the measurement type).
+	    System.out.println(REVOLUTION.divide(MINUTE).getSystemUnit());
+	    // Dimension checking (allows/disallows conversions)
+	    System.out.println(ELECTRON_VOLT.isCompatible(WATT.multiply(HOUR)));
+	    // Retrieval of the unit dimension (depends upon the current model).
+	    System.out.println(ELECTRON_VOLT.getDimension());
+	    System.out.println(KILOGRAM.equals(KILO(GRAM)));
+	    System.out.println(KILOGRAM.equals(KILO(OUNCE)));
+	    
+	    LengthAmount foot = new LengthAmount(1, FOOT); 
+	    LengthAmount inches = new LengthAmount(24, INCH);
+	    double ratio = INCH.getConverterTo(FOOT).convert(24);
+	    IMeasure<Length> lRatio = inches.to(FOOT);
+	    //long ratio = inches.longValue(FOOT);
+	    //double ratio = foot.doubleValue(INCH);
+	    System.out.println("Ratio: " + ratio);
+	    @SuppressWarnings("unchecked")
+		IMeasure<Length> iRatio = (IMeasure<Length>) foot.divide(inches);
+	    System.out.println("Ratio2: " + iRatio);
+	    System.out.println("Ratio3: " + lRatio);
+	    //BaseAmount<Length> qaRatio = (BaseAmount<Length>)lRatio;
+	    //System.out.println(qaRatio.getNumber());
+	    
+	    IMeasure<Length> l1 = new LengthAmount(1, MILE);
+	    IMeasure<Length> l2 = l1.to(FOOT);
+	    System.out.println(l1 + " = " + l2);
+	    
+	    LengthAmount x = new LengthAmount(BigDecimal.valueOf(1.0001d), SI.Prefix.KILO(SI.METRE));
+	    IMeasure<Length> xi = x.to(SI.METRE);
+	    IMeasure<Length> xj = x.to(SI.METRE, MathContext.UNLIMITED);
+	    System.out.println("x="+x+" xi="+xi+"+xj="+xj);
+	    // Results in: x=1.0001 km xi=1000.0 m
+
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Demo.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Demo.java
new file mode 100644
index 0000000..8a4ecd4
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Demo.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, JScience and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil, Martin Desruisseaux - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console;
+
+import static org.eclipse.uomo.units.SI.*;
+import static org.eclipse.uomo.units.SI.Prefix.*;
+import static org.eclipse.uomo.units.impl.system.USCustomary.FOOT;
+import static org.eclipse.uomo.examples.units.types.PolishObsolete.*;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.eclipse.uomo.units.impl.quantity.MassAmount;
+import org.eclipse.uomo.units.impl.quantity.TimeAmount;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.quantity.Time;
+
+/**
+ * @author <a href="mailto:desruisseaux@users.sourceforge.net">Martin Desruisseaux</a>
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.7 ($Revision: 210 $), $Date: 2011-12-29 23:34:46 +0100 (Do, 29 Dec 2011) $
+ */
+public class Demo {
+
+	private static IMeasure<Length> getSomeLength() {
+        return new LengthAmount(20, METRE);
+    }
+	
+	private static IMeasure<Length> getMoreLength() {
+        return new LengthAmount(20, METRE);
+    }
+	
+	private static IMeasure<Mass> getSomeMass() {
+        return new MassAmount(30, KILOGRAM);
+    }
+	
+	private static IMeasure<Mass> getMoreMass() {
+		return new MassAmount(30, KILOGRAM);
+	}
+	
+	private static IMeasure<Time> getTime() {
+		return new TimeAmount(10, SECOND);
+	}
+
+    public static void main(String[] args) {
+    	IMeasure<Length> someLength = getSomeLength();
+        System.out.println("l = " + someLength);
+        IMeasure<Length> moreLength = getMoreLength();
+        System.out.println("l2 = " + moreLength);
+        System.out.println();
+
+        IMeasure<Mass> someMass = getSomeMass();
+        System.out.println("toString = " + someMass);        
+        IMeasure<Mass> moreMass = getMoreMass();
+        System.out.println("toString2 = " + moreMass);
+        System.out.println();
+        
+        IMeasure<Time> time = getTime();
+        System.out.println("toString = " + time);
+        
+        IMeasure<?> result = moreLength.divide(time);
+        System.out.println("toString3 = " + result);
+        
+        IMeasure<Length> convertedLength = moreLength.to(FOOT);
+        System.out.println("converted = " + convertedLength);
+        
+       IMeasure<Length> convertedLengthPL = moreLength.to(ELL);
+       System.out.println("converted (PL) = " + convertedLengthPL);
+        
+        
+        System.out.println();
+        someLength = new LengthAmount(1, MILLI(METRE));
+        System.out.println("len1 = " + someLength);
+        IMeasure<Length> someMoreLength = new LengthAmount(400, KILO(METRE));
+        someMass = new MassAmount(50, MILLI(GRAM));
+        System.out.println("mass1 = " + someMass);
+        System.out.println("len2 = " + someMoreLength);
+    }
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/HelloUnits.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/HelloUnits.java
new file mode 100644
index 0000000..4eccd42
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/HelloUnits.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2005, 2012, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.quantity.AreaAmount;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.eclipse.uomo.units.impl.quantity.TimeAmount;
+import org.eclipse.uomo.units.impl.system.USCustomary;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+import org.unitsofmeasurement.quantity.Acceleration;
+import org.unitsofmeasurement.quantity.Area;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Time;
+
+public class HelloUnits {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		LengthAmount length = new LengthAmount(10, SI.METRE);
+//		LengthAmount length = new LengthAmount(10, SI.KILOGRAM); // this won't work ;-)
+		
+		System.out.println(length);
+		Unit<Length> lenUnit =  length.unit();
+    	//System.out.println(lenUnit);
+		
+		System.out.print(length.doubleValue(USCustomary.FOOT)); 
+		System.out.println(" " + USCustomary.FOOT);
+//		System.out.println(length.doubleValue(USCustomary.POUND)); // this won't work either.
+		UnitConverter inchConverter = lenUnit.getConverterTo(USCustomary.INCH);
+		System.out.print(inchConverter.convert(length.getNumber().doubleValue()));		
+		System.out.println(" " + USCustomary.INCH);
+		
+		@SuppressWarnings("unchecked")
+		AreaAmount area = new AreaAmount(length.getNumber().doubleValue() * length.getNumber().doubleValue(), 
+				(Unit<Area>) length.unit().multiply(SI.METRE));
+		System.out.println(area);
+		
+		// Equivalent to 
+		IMeasure<Length> meters = new LengthAmount(5, SI.METRE);
+		IMeasure<Time> secs = new TimeAmount(2, SI.SECOND);
+		@SuppressWarnings("unchecked")
+		IMeasure<Acceleration> speed = (IMeasure<Acceleration>) meters.divide(secs);
+		System.out.println(meters + 
+				"; " + secs +
+				"; " + speed);
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Messages.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Messages.java
new file mode 100644
index 0000000..dbbf4bf
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/Messages.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+	public static String Planet_Radius;
+	public static String Planet_SurfaceGravity;
+	public static String Planet_Usage;
+	public static String Planet_SurfaceWeight;
+	public static String REP_100mR;
+	public static String REP_1R;
+	public static String REP_2dot5R;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/UnitsExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/UnitsExample.java
new file mode 100644
index 0000000..1809bdb
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/UnitsExample.java
@@ -0,0 +1,21 @@
+package org.eclipse.uomo.examples.units.console;
+
+import org.unitsofmeasurement.quantity.Acceleration;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Time;
+import org.unitsofmeasurement.unit.Unit;
+
+import static org.eclipse.uomo.units.SI.*;
+
+public class UnitsExample {
+	  public static void main(String[] args) {
+	    Unit<Length> distance = METRE.multiply(5);
+	    Unit<Time> time = SECOND.multiply(10);
+	    @SuppressWarnings("unchecked")
+		Unit<Acceleration> speed = (Unit<Acceleration>) distance.divide(time);
+
+	    System.out.println("Speed = " + speed);
+
+//	    Unit<?> nonsense = distance.add(time);
+	  }
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/EqualsTest.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/EqualsTest.java
new file mode 100644
index 0000000..b060a77
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/EqualsTest.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2012, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import static org.eclipse.uomo.units.SI.Prefix.KILO;
+
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.quantity.MassAmount;
+
+public class EqualsTest {
+	public static void main(String[] args) {
+		// TODO Bug 338334 this could be a JUnit test, convert into after issue
+		// resolved.
+		MassAmount mass = new MassAmount(1000, SI.GRAM);
+		MassAmount mass2 = new MassAmount(1, SI.KILOGRAM);
+		MassAmount mass3 = new MassAmount(1, KILO(SI.GRAM));
+		System.out.println(mass.equals(mass2) + "; " + mass.equals(mass3)
+				+ "; " + mass2.equals(mass3));
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/KawaExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/KawaExample.java
new file mode 100644
index 0000000..69ae5b6
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/KawaExample.java
@@ -0,0 +1,35 @@
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.quantity.LengthAmount;
+import org.eclipse.uomo.units.impl.quantity.MassAmount;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.quantity.Mass;
+import org.unitsofmeasurement.quantity.Quantity;
+import org.unitsofmeasurement.unit.Unit;
+
+
+public class KawaExample {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		Unit<Length> m = SI.METRE;
+		Unit<Mass> g = SI.GRAM;
+		
+		Unit<?> result = g.multiply(m);
+		System.out.println(result);
+		
+		IMeasure<Length> q1 = new LengthAmount(1, m);
+		System.out.println(q1);
+		IMeasure<Mass> q2 = new MassAmount(1, g);
+		System.out.println(q2);
+		Quantity<?> q3 = q1.multiply(q2);
+		System.out.println(q3);
+//		Quantity<Length> q4 = q1.add(q2); // this fails at compile time, not at runtime
+//		System.out.println(q4);
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/NamesExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/NamesExample.java
new file mode 100644
index 0000000..d3d125e
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/NamesExample.java
@@ -0,0 +1,16 @@
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import com.ibm.icu.impl.ICUService;
+
+public class NamesExample {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		// TODO Auto-generated method stub
+		ICUService.Factory factory = new ICUService.SimpleFactory((Object)"a", "b");
+		System.out.println(factory);
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/OSGiRequirements.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/OSGiRequirements.java
new file mode 100644
index 0000000..c2e02a2
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/OSGiRequirements.java
@@ -0,0 +1,36 @@
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.system.Imperial;
+import org.eclipse.uomo.util.Parser;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+import org.unitsofmeasurement.unit.UnitConverter;
+
+/**
+ * 
+ * @author Werner Keil
+ * @version 1.1
+ * <p>
+ * Thanks to Barry for his input and inspiration.
+ * </p>
+ */
+public class OSGiRequirements {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) throws Exception {
+		SystemOfUnits system = SI.getInstance();
+		Unit<Length> km = SI.METRE.multiply(1000);
+		Unit<Length> foot = Imperial.INCH.multiply(12);
+		UnitConverter converter = km.getConverterTo(foot);
+		Parser<String, Unit<?>> p = null;
+		Unit<?> userDefinedUnit = (p == null) ? null : p.parse("m/s^2"); // this is not a valid UCUM expression;-)
+		System.out.println("0.1 km in feet = " + converter.convert(0.1));
+		System.out.println(system.getName());
+		System.out.println(userDefinedUnit);
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/ObsoleteUnitsExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/ObsoleteUnitsExample.java
new file mode 100644
index 0000000..6e4a2a0
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/ObsoleteUnitsExample.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2012, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import static org.eclipse.uomo.examples.units.types.GermanObsolete.*;
+import static org.eclipse.uomo.units.impl.system.USCustomary.FOOT;
+import static org.eclipse.uomo.units.SI.*;
+
+import org.eclipse.uomo.examples.units.types.PolishObsolete;
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.impl.BaseAmount;
+import org.unitsofmeasurement.quantity.Length;
+
+/**
+ * @author Werner Keil
+ *
+ */
+public class ObsoleteUnitsExample {
+
+	/**
+	 * @param args
+	 */
+	@SuppressWarnings("deprecation")
+	public static void main(String[] args) {
+		IMeasure<Length> l = BaseAmount.valueOf(10, METRE);
+		System.out.println(l);
+		System.out.println(l.to(FOOT));
+		System.out.println(l.to(FOOT_ZURICH));
+		System.out.println(l.to(STONE_FOOT));
+		System.out.println(l.to(FOOT_LAUSANNE));
+		System.out.println(l.to(ELL_NORTH));
+		System.out.println(l.to(ELL_SOUTH));
+		System.out.println(l.to(PolishObsolete.ELL));
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/RadiologicalEmergencyPreparedness.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/RadiologicalEmergencyPreparedness.java
new file mode 100644
index 0000000..e324d07
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/RadiologicalEmergencyPreparedness.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import static org.eclipse.uomo.units.SI.Prefix.MILLI;
+import static org.eclipse.uomo.units.SI.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.uomo.units.IMeasure;
+import org.eclipse.uomo.units.impl.quantity.IonizingRadiationAmount;
+import org.unitsofmeasurement.quantity.IonizingRadiation;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * 
+ * @see <a
+ *      href="http://www.nema.ne.gov/technological/dose-limits.html">NEMA:
+ *      Radiological Emergency Preparedness</a>
+ */
+public class RadiologicalEmergencyPreparedness {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		Map <IMeasure<IonizingRadiation>, String> repMap = new HashMap<IMeasure<IonizingRadiation>, String>();
+		IonizingRadiationAmount ira = new IonizingRadiationAmount(100, MILLI(ROENTGEN));
+		// TODO fix formatting for mR
+		
+		repMap.put(ira, SandboxMessages.REP_100mR);
+		ira = new IonizingRadiationAmount(1, ROENTGEN);
+		repMap.put(ira, SandboxMessages.REP_1R);
+		ira = new IonizingRadiationAmount(2.5, ROENTGEN);
+		repMap.put(ira, SandboxMessages.REP_2dot5R);
+		
+		for (IMeasure<IonizingRadiation> dosimeterLimit : repMap.keySet()) {			
+			System.out.println(dosimeterLimit + " :: " + repMap.get(dosimeterLimit));
+		}
+		
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SandboxMessages.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SandboxMessages.java
new file mode 100644
index 0000000..116bfc9
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SandboxMessages.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import org.eclipse.osgi.util.NLS;
+
+class SandboxMessages extends NLS {
+	private static final String BUNDLE_NAME = SandboxMessages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+	public static String REP_100mR;
+	public static String REP_1R;
+	public static String REP_2dot5R;
+	
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, SandboxMessages.class);
+	}
+
+	private SandboxMessages() {
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SeismicExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SeismicExample.java
new file mode 100644
index 0000000..57ad06c
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/SeismicExample.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil, Ikayzo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import org.eclipse.uomo.examples.units.types.Seismic;
+import org.eclipse.uomo.units.impl.quantity.EnergyAmount;
+import com.ibm.icu.util.Measure;
+
+/**
+ * @author Werner Keil
+ *
+ */
+public class SeismicExample {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		Measure e = new EnergyAmount(8.3, Seismic.RICHTER_MAGNITUDE);
+		System.out.println(e);
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/TemperatureExample.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/TemperatureExample.java
new file mode 100644
index 0000000..447543b
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/console/sandbox/TemperatureExample.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2005, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.console.sandbox;
+
+import org.eclipse.uomo.units.QuantityAmount;
+import org.eclipse.uomo.units.SI;
+import org.eclipse.uomo.units.impl.quantity.TemperatureAmount;
+import org.eclipse.uomo.units.impl.system.USCustomary;
+import org.unitsofmeasurement.quantity.Temperature;
+
+/**
+ * @author Werner Keil
+ * @version 1.0
+ *
+ */
+public class TemperatureExample {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		TemperatureAmount temp1 = new TemperatureAmount(0, SI.CELSIUS);
+		QuantityAmount<Temperature> temp2 = temp1.to(SI.KELVIN);
+		QuantityAmount<Temperature> temp3 = temp1.to(USCustomary.FAHRENHEIT);
+		System.out.println(temp1 + " -> " + temp2 + " -> " + temp3);
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/GermanObsolete.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/GermanObsolete.java
new file mode 100644
index 0000000..6c64104
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/GermanObsolete.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.types;
+
+import static org.eclipse.uomo.units.SI.METRE;
+import static org.eclipse.uomo.units.SI.Prefix.MILLI;
+import static org.eclipse.uomo.units.impl.system.USCustomary.FOOT;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+import com.ibm.icu.math.BigDecimal;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.0.1
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/German_obsolete_units_of_measurement">Wikipedia: German Obsolete Units of Measurement</a>
+ * @deprecated
+ */
+public class GermanObsolete extends AbstractSystemOfUnits {
+
+	/**
+	 * Distance between elbow and fingertip. In the North, often 2 feet,
+	 * In Prussia 17 / 8 feet, in the South variable, often 2½ feet.
+	 * The smallest known German Elle is 402.8 mm, the longest 811 mm.
+	 * */
+	public static final  Unit<Length> ELL_NORTH = FOOT.multiply(2);
+	
+	/**
+	 * Distance between elbow and fingertip. In the North, often 2 feet,
+	 * In Prussia 17 / 8 feet, in the South variable, often 2½ feet.
+	 * The smallest known German Elle is 402.8 mm, the longest 811 mm.
+	 * */
+	public static final  Unit<Length> ELL_SOUTH = FOOT.multiply(2.5d);
+	
+	/** The Fuß or German foot varied widely from place to place in the German-speaking world, and also with time. 
+	 * In some places, more than one type of Fuß was in use.
+	 * @see <a href="http://en.wikipedia.org/wiki/German_obsolete_units_of_measurement#Fu.C3.9F_.28foot.29">Wikipedia: German Obsolete - Fuß</a>
+	 * */
+	public static final  Unit<Length> FOOT_ZURICH = MILLI(METRE).multiply(301);
+	
+	/** The Fuß or German foot varied widely from place to place in the German-speaking world, and also with time. 
+	 * In some places, more than one type of Fuß was in use.
+	 * @see <a href="http://en.wikipedia.org/wiki/German_obsolete_units_of_measurement#Fu.C3.9F_.28foot.29">Wikipedia: German Obsolete - Fuß</a>
+	 * */
+	public static final  Unit<Length> FOOT_ZUG = FOOT_ZURICH;
+	
+	/**
+	 * Fuß, Lausanne, Canton of Waadt<p> 
+	 * The Fuß or German foot varied widely from place to place in the German-speaking world, and also with time. 
+	 * In some places, more than one type of Fuß was in use.
+	 * @see <a href="http://en.wikipedia.org/wiki/German_obsolete_units_of_measurement#Fu.C3.9F_.28foot.29">Wikipedia: German Obsolete - Fuß</a>
+	 * */
+	public static final  Unit<Length> FOOT_LAUSANNE = MILLI(METRE).multiply(293);
+	
+	/**
+	 * Steinfuß, Zug, Canton of<p> 
+	 * The Fuß or German foot varied widely from place to place in the German-speaking world, and also with time. 
+	 * In some places, more than one type of Fuß was in use.
+	 * @see <a href="http://en.wikipedia.org/wiki/German_obsolete_units_of_measurement#Fu.C3.9F_.28foot.29">Wikipedia: German Obsolete - Fuß</a>
+	 * */
+	public static final  Unit<Length> STONE_FOOT = MILLI(METRE).multiply(268);
+	
+	@Override
+	public String getName() {
+		return GermanObsolete.class.getSimpleName();
+	}
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private GermanObsolete() {
+    }
+	
+	/**
+	 * The singleton instance of {@code Seismic}.
+	 */
+	private static final GermanObsolete INSTANCE = new GermanObsolete();
+
+	/**
+	 * Returns the singleton instance of this class.
+	 * 
+	 * @return the Seismic system instance.
+	 */
+	public static final SystemOfUnits getInstance() {
+		return INSTANCE;
+	}	
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/PolishObsolete.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/PolishObsolete.java
new file mode 100644
index 0000000..e415c89
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/PolishObsolete.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2012, 2013, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.types;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.quantity.Length;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.0.2, 2013-05-14
+ * @see <a
+ *      href="http://en.wikipedia.org/wiki/Obsolete_Polish_units_of_measurement">Wikipedia: Obsolete Polish Uits of Measurement</a>
+ * @deprecated
+ */
+public class PolishObsolete extends AbstractSystemOfUnits {
+
+	/** The basic unit of length - the ell or łokieć in Polish - was set to 0.5955 metres 
+	 *  
+	 * */
+	public static final  Unit<Length> ELL = SI.METRE.multiply(0.5955d);
+	
+	@Override
+	public String getName() {
+		return PolishObsolete.class.getSimpleName();
+	}
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private PolishObsolete() {
+    }
+	
+	/**
+	 * The singleton instance of {@code Seismic}.
+	 */
+	private static final PolishObsolete INSTANCE = new PolishObsolete();
+
+	/**
+	 * Returns the singleton instance of this class.
+	 * 
+	 * @return the Seismic system instance.
+	 */
+	public static final SystemOfUnits getInstance() {
+		return INSTANCE;
+	}	
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/Seismic.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/Seismic.java
new file mode 100644
index 0000000..8244f4a
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/java/org/eclipse/uomo/examples/units/types/Seismic.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2005, 2011, Werner Keil and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Werner Keil - initial API and implementation
+ */
+package org.eclipse.uomo.examples.units.types;
+
+import org.eclipse.uomo.units.AbstractSystemOfUnits;
+import org.eclipse.uomo.units.SI;
+import org.unitsofmeasurement.quantity.Energy;
+import org.unitsofmeasurement.unit.SystemOfUnits;
+import org.unitsofmeasurement.unit.Unit;
+
+/**
+ * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
+ * @version 0.4.1
+ */
+public class Seismic extends AbstractSystemOfUnits {
+
+	// Richter scale.
+	public static final  Unit<Energy> RICHTER_MAGNITUDE = (SI.JOULE.multiply(1.5d)).add(4.4d);
+	// e = 10 ^ (4.4 +3 M / 2)
+		//SI.JOULE.divide(Math.pow(10, 4.4d)).transform(new LogConverter());
+	
+	@Override
+	public String getName() {
+		return Seismic.class.getSimpleName();
+	}
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private Seismic() {
+    }
+	
+	/**
+	 * The singleton instance of {@code Seismic}.
+	 */
+	private static final Seismic INSTANCE = new Seismic();
+
+	/**
+	 * Returns the singleton instance of this class.
+	 * 
+	 * @return the Seismic system instance.
+	 */
+	public static final SystemOfUnits getInstance() {
+		return INSTANCE;
+	}	
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/.placeholder b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/.placeholder
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/examples/units/messages.properties b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/examples/units/messages.properties
new file mode 100644
index 0000000..36b8ad0
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/examples/units/messages.properties
@@ -0,0 +1,17 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2005, 2011, Werner Keil and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil - initial API and implementation
+#
+
+REP_100mR = Turn back value. Dosimeter reading allowed for performing Emergency Worker assignments. Report to the Radiological Officer or assigned State Health Physicist for further instructions.
+
+REP_1R = Dose allowed for assignments involving protection of valuable property.
+
+REP_2dot5R = Dose allowed for assignments involving lifesaving protection of large populations.
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties
new file mode 100644
index 0000000..4f04ad9
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages.properties
@@ -0,0 +1,24 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2013, Werner Keil and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil - initial API and implementation
+#
+
+# Seismic Units
+org.eclipse.uomo.examples.units.types.Seismic.RICHTER_MAGNITUDE            = r
+
+# German Obsolete
+org.eclipse.uomo.examples.units.types.GermanObsolete.ELL_NORTH           = ell.n
+org.eclipse.uomo.examples.units.types.GermanObsolete.ELL_SOUTH           = ell.s
+org.eclipse.uomo.examples.units.types.GermanObsolete.FOOT_ZURICH           = ft
+org.eclipse.uomo.examples.units.types.GermanObsolete.STONE_FOOT            = stft
+org.eclipse.uomo.examples.units.types.GermanObsolete.FOOT_LAUSANNE         = [ft]
+
+# Polish Obsolete
+org.eclipse.uomo.examples.units.types.PolishObsolete.ELL           = ell
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties
new file mode 100644
index 0000000..aa2362e
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/messages_de.properties
@@ -0,0 +1,24 @@
+#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)
+#
+# Copyright (c) 2013, Werner Keil and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Werner Keil - initial API and implementation
+#
+
+# Seismic Units
+org.eclipse.uomo.examples.units.types.Seismic.RICHTER_MAGNITUDE            = r.sk
+
+# German Obsolete
+org.eclipse.uomo.examples.units.types.GermanObsolete.ELL_NORTH             = elle (N)
+org.eclipse.uomo.examples.units.types.GermanObsolete.ELL_SOUTH          = elle (S)
+org.eclipse.uomo.examples.units.types.GermanObsolete.FOOT_ZURICH           = fu\u00DF
+org.eclipse.uomo.examples.units.types.GermanObsolete.STONE_FOOT            = steinfu\u00DF
+org.eclipse.uomo.examples.units.types.GermanObsolete.FOOT_LAUSANNE         = [fu\u00DF]
+
+# Polish Obsolete
+org.eclipse.uomo.examples.units.types.PolishObsolete.ELL           = elle
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/package-info.java b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/package-info.java
new file mode 100644
index 0000000..a8f3992
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/main/resources/org/eclipse/uomo/units/impl/format/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author Werner
+ *
+ */
+package org.eclipse.uomo.units.impl.format;
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/.placeholder b/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/.placeholder
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/org/eclipse/uomo/examples/units/console/EqualsTest.java b/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/org/eclipse/uomo/examples/units/console/EqualsTest.java
new file mode 100644
index 0000000..bdc321d
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/test/java/org/eclipse/uomo/examples/units/console/EqualsTest.java
@@ -0,0 +1,21 @@
+package org.eclipse.uomo.examples.units.console;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
+
+import java.math.BigInteger;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class EqualsTest {
+
+	@Test
+	@Ignore("this will fail due to inconsistency of JDK")
+	public void testInteger() {
+		Number n1 = Integer.valueOf(2);
+		Number n2 = BigInteger.valueOf(2);
+		assertThat(n1, is(n2));
+	}
+
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.console/src/test/resources/.placeholder b/examples/units/org.eclipse.uomo.examples.units.console/src/test/resources/.placeholder
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.console/src/test/resources/.placeholder
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/.classpath b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.classpath
new file mode 100644
index 0000000..9d68a1f
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/.gitignore b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.gitignore
new file mode 100644
index 0000000..d90e434
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.gitignore
@@ -0,0 +1,2 @@
+/.settings
+/target
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/.project b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.project
new file mode 100644
index 0000000..4fd8d13
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.project
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.examples.units.pluginsample</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.springframework.ide.eclipse.core.springbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+		<nature>org.springframework.ide.eclipse.core.springnature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/.springBeans b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.springBeans
new file mode 100644
index 0000000..6f4c287
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[2.5.1.201011101000-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+	</configs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/META-INF/MANIFEST.MF b/examples/units/org.eclipse.uomo.examples.units.pluginsample/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..868c52f
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: UOMoPluginSample
+Bundle-SymbolicName: UOMoPluginSample;singleton:=true
+Bundle-Vendor: Eclipse OSBP
+Bundle-Version: 0.1.0.SNAPSHOT
+Bundle-Activator: org.eclipse.uomo.examples.units.pluginsample.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.unitsofmeasurement.unit-api;bundle-version="0.6.0",
+ org.eclipse.uomo.core;bundle-version="0.2.0",
+ org.eclipse.uomo.units;bundle-version="0.5.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,
+ OSGi/Minimum-1.1
+Export-Package: org.eclipse.uomo.examples.units.pluginsample,
+ org.eclipse.uomo.examples.units.pluginsample.views
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/build.properties b/examples/units/org.eclipse.uomo.examples.units.pluginsample/build.properties
new file mode 100644
index 0000000..80bc250
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/build.properties
@@ -0,0 +1,6 @@
+source.. = src/main/java/,\
+           src/main/resources/,\
+           src/test/java/,\
+           src/test/resources/
+bin.includes = META-INF/,\
+               .
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/contexts.xml b/examples/units/org.eclipse.uomo.examples.units.pluginsample/contexts.xml
new file mode 100644
index 0000000..02e26e4
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/contexts.xml
@@ -0,0 +1,12 @@
+<contexts>
+	<context id="viewer" title="Sample View">
+		<description>This is the context help for the sample view with a table viewer. It was generated by a PDE template.</description>
+		<topic href="/PLUGINS_ROOT/org.eclipse.platform.doc.isv/guide/ua_help_context.htm" label="Context-sensitive help">
+			<enablement>
+				<with variable="platform">
+	            	<test property="org.eclipse.core.runtime.isBundleInstalled" args="org.eclipse.platform.doc.isv"/>
+	     		</with>
+			</enablement>
+		</topic>
+	</context>
+</contexts>
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/plugin.xml b/examples/units/org.eclipse.uomo.examples.units.pluginsample/plugin.xml
new file mode 100644
index 0000000..fa8aad1
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            name="Sample Category"
+            id="UOMoPluginSample">
+      </category>
+      <view
+            name="Sample View"
+            icon="src/main/resources/icons/sample.gif"
+            category="UOMoPluginSample"
+            class="uomopluginsample.views.SampleView"
+            id="uomopluginsample.views.SampleView">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension
+            targetID="org.eclipse.jdt.ui.JavaPerspective">
+         <view
+               ratio="0.5"
+               relative="org.eclipse.ui.views.TaskList"
+               relationship="right"
+               id="uomopluginsample.views.SampleView">
+         </view>
+      </perspectiveExtension>
+   </extension>
+   <extension
+         point="org.eclipse.help.contexts">
+      <contexts
+            file="contexts.xml">
+      </contexts>
+   </extension>
+
+</plugin>
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/pom.xml b/examples/units/org.eclipse.uomo.examples.units.pluginsample/pom.xml
new file mode 100644
index 0000000..453020a
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo.examples.units</artifactId>
+    <groupId>org.eclipse.uomo.examples</groupId>
+    <version>0.1.0.SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>org.eclipse.uomo.examples.units.pluginsample</artifactId>
+  <name>UOMo Units Plugin Sample</name>
+  <dependencies>
+  	<dependency>
+  		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+  		<artifactId>org.eclipse.uomo.core</artifactId>
+  		<version>0.2.0.SNAPSHOT</version>
+  		<scope>compile</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.unitsofmeasurement</groupId>
+  		<artifactId>unit-api</artifactId>
+  		<version>0.6.1</version>
+  		<type>bundle</type>
+  		<scope>compile</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+  		<artifactId>org.eclipse.uomo.units</artifactId>
+  		<version>${project.version}</version>
+  		<type>jar</type>
+  		<scope>compile</scope>
+  	</dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/Activator.java b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/Activator.java
new file mode 100644
index 0000000..743aab9
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/Activator.java
@@ -0,0 +1,61 @@
+package org.eclipse.uomo.examples.units.pluginsample;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "UOMoPluginSample"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+}
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/views/SampleView.java b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/views/SampleView.java
new file mode 100644
index 0000000..cd05dac
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/java/org/eclipse/uomo/examples/units/pluginsample/views/SampleView.java
@@ -0,0 +1,199 @@
+package org.eclipse.uomo.examples.units.pluginsample.views;
+
+import static org.eclipse.uomo.units.SI.*;
+import static org.eclipse.uomo.units.impl.system.USCustomary.LITER;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.*;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.SWT;
+
+import org.eclipse.uomo.units.impl.quantity.*;
+
+/**
+ * This sample class demonstrates how to plug-in a new
+ * workbench view. The view shows data obtained from the
+ * model. The sample creates a dummy model on the fly,
+ * but a real implementation would connect to the model
+ * available either in this or another plug-in (e.g. the workspace).
+ * The view is connected to the model using a content provider.
+ * <p>
+ * The view uses a label provider to define how model
+ * objects should be presented in the view. Each
+ * view can present the same model objects using
+ * different labels and icons, if needed. Alternatively,
+ * a single label provider can be shared between views
+ * in order to ensure that objects of the same type are
+ * presented in the same way everywhere.
+ * <p>
+ */
+
+public class SampleView extends ViewPart {
+
+	/**
+	 * The ID of the view as specified by the extension.
+	 */
+	public static final String ID = "uomopluginsample.views.SampleView";
+
+	private TableViewer viewer;
+	private Action action1;
+	private Action action2;
+	private Action doubleClickAction;
+	private final LengthAmount length;
+	private final MassAmount mass;
+	private final VolumeAmount volume;
+	
+	/*
+	 * The content provider class is responsible for
+	 * providing objects to the view. It can wrap
+	 * existing objects in adapters or simply return
+	 * objects as-is. These objects may be sensitive
+	 * to the current input of the view, or ignore
+	 * it and always show the same content 
+	 * (like Task List, for example).
+	 */
+	 
+	class ViewContentProvider implements IStructuredContentProvider {
+		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+		}
+		public void dispose() {
+		}
+		public Object[] getElements(Object parent) {
+			return new Object[] { length, mass, volume };
+		}
+	}
+	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
+		public String getColumnText(Object obj, int index) {
+			return getText(obj);
+		}
+		public Image getColumnImage(Object obj, int index) {
+			return getImage(obj);
+		}
+		public Image getImage(Object obj) {
+			return PlatformUI.getWorkbench().
+					getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+		}
+	}
+	class NameSorter extends ViewerSorter {
+	}
+
+	/**
+	 * The constructor.
+	 */
+	public SampleView() {
+		length = new LengthAmount(1,METRE);
+		mass = new MassAmount(2, KILOGRAM);
+		volume = new VolumeAmount(3, LITER);
+	}
+
+	/**
+	 * This is a callback that will allow us
+	 * to create the viewer and initialize it.
+	 */
+	public void createPartControl(Composite parent) {
+		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+		viewer.setContentProvider(new ViewContentProvider());
+		viewer.setLabelProvider(new ViewLabelProvider());
+		viewer.setSorter(new NameSorter());
+		viewer.setInput(getViewSite());
+
+		// Create the help context id for the viewer's control
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "UOMoPluginSample.viewer");
+		makeActions();
+		hookContextMenu();
+		hookDoubleClickAction();
+		contributeToActionBars();
+	}
+
+	private void hookContextMenu() {
+		MenuManager menuMgr = new MenuManager("#PopupMenu");
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+				SampleView.this.fillContextMenu(manager);
+			}
+		});
+		Menu menu = menuMgr.createContextMenu(viewer.getControl());
+		viewer.getControl().setMenu(menu);
+		getSite().registerContextMenu(menuMgr, viewer);
+	}
+
+	private void contributeToActionBars() {
+		IActionBars bars = getViewSite().getActionBars();
+		fillLocalPullDown(bars.getMenuManager());
+		fillLocalToolBar(bars.getToolBarManager());
+	}
+
+	private void fillLocalPullDown(IMenuManager manager) {
+		manager.add(action1);
+		manager.add(new Separator());
+		manager.add(action2);
+	}
+
+	private void fillContextMenu(IMenuManager manager) {
+		manager.add(action1);
+		manager.add(action2);
+		// Other plug-ins can contribute there actions here
+		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+	}
+	
+	private void fillLocalToolBar(IToolBarManager manager) {
+		manager.add(action1);
+		manager.add(action2);
+	}
+
+	private void makeActions() {
+		action1 = new Action() {
+			public void run() {
+				showMessage("Action 1 executed");
+			}
+		};
+		action1.setText("Action 1");
+		action1.setToolTipText("Action 1 tooltip");
+		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
+			getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
+		
+		action2 = new Action() {
+			public void run() {
+				showMessage("Action 2 executed");
+			}
+		};
+		action2.setText("Action 2");
+		action2.setToolTipText("Action 2 tooltip");
+		action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
+				getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
+		doubleClickAction = new Action() {
+			public void run() {
+				ISelection selection = viewer.getSelection();
+				Object obj = ((IStructuredSelection)selection).getFirstElement();
+				showMessage("Double-click detected on "+obj.toString());
+			}
+		};
+	}
+
+	private void hookDoubleClickAction() {
+		viewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				doubleClickAction.run();
+			}
+		});
+	}
+	private void showMessage(String message) {
+		MessageDialog.openInformation(
+			viewer.getControl().getShell(),
+			"Sample View",
+			message);
+	}
+
+	/**
+	 * Passing the focus request to the viewer's control.
+	 */
+	public void setFocus() {
+		viewer.getControl().setFocus();
+	}
+}
\ No newline at end of file
diff --git a/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/resources/icons/sample.gif b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/resources/icons/sample.gif
new file mode 100644
index 0000000..34fb3c9
--- /dev/null
+++ b/examples/units/org.eclipse.uomo.examples.units.pluginsample/src/main/resources/icons/sample.gif
Binary files differ
diff --git a/examples/units/pom.xml b/examples/units/pom.xml
new file mode 100644
index 0000000..079365c
--- /dev/null
+++ b/examples/units/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.examples</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.examples.units</artifactId>
+	<packaging>pom</packaging>
+	<name>Eclipse UOMo Units Examples</name>
+	<modules>
+	   <module>org.eclipse.uomo.examples.units.console</module>
+	   <!--  >module>org.eclipse.uomo.examples.units.pluginsample</module -->
+    <module>org.eclipse.uomo.examples.units.android</module>
+  </modules>
+	<!-- ==================================================== -->
+    <!-- Repositories. This is where Maven looks for dependencies. 
+         The Maven repository is implicit and doesn't need 
+         to be specified. -->
+    <!-- ==================================================== -->
+    <repositories>
+        <repository>
+            <id>maven-geotoolkit.org</id>
+            <name>GeoToolkit Repository for Maven</name>
+            <url>http://maven.geotoolkit.org/</url>
+        </repository>
+        
+        <repository>
+            <id>OpenL10n</id>
+            <name>Openl10.net</name>
+            <url>http://nexus.openl10n.net/content/groups/public/</url>
+        </repository>
+    </repositories>
+	
+    <groupId>org.eclipse.uomo.examples.units</groupId>
+</project>
\ No newline at end of file
diff --git a/features/.gitignore b/features/.gitignore
new file mode 100644
index 0000000..834befa
--- /dev/null
+++ b/features/.gitignore
@@ -0,0 +1,3 @@
+/src
+/.settings
+/target
diff --git a/features/.project b/features/.project
new file mode 100644
index 0000000..01b71cd
--- /dev/null
+++ b/features/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>features</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.uomo.feature/.classpath b/features/org.eclipse.uomo.feature/.classpath
new file mode 100644
index 0000000..23946e4
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/.classpath
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/features/org.eclipse.uomo.feature/.gitignore b/features/org.eclipse.uomo.feature/.gitignore
new file mode 100644
index 0000000..e7da900
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/.gitignore
@@ -0,0 +1,3 @@
+/target
+/.settings
+/target
diff --git a/features/org.eclipse.uomo.feature/.project b/features/org.eclipse.uomo.feature/.project
new file mode 100644
index 0000000..e40f7dd
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/.project
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.common.project.facet.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.babel.editor.rbeBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+		<nature>org.eclipse.babel.editor.rbeNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.uomo.feature/build.properties b/features/org.eclipse.uomo.feature/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/features/org.eclipse.uomo.feature/feature.xml b/features/org.eclipse.uomo.feature/feature.xml
new file mode 100644
index 0000000..d806680
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/feature.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.uomo.feature"
+      label="Eclipse UOMo"
+      version="0.6.0.qualifier"
+      provider-name="Eclipse.org"
+      plugin="org.eclipse.uomo.ui">
+
+   <description url="http://www.eclipse.org/uomo">
+      Eclipse UOMo
+   </description>
+
+   <copyright url="http://www.example.com/copyright">
+      Eclipse Foundation Software User Agreement
+
+February 1, 2011
+
+Usage Of Content
+
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY &quot;CONTENT&quot;). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.
+
+Applicable Licenses
+
+Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, &quot;Program&quot; will mean the Content.
+
+Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code repository (&quot;Repository&quot;) in software modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).
+
+Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).
+Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named &quot;plugins&quot;.
+A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;. Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins and/or Fragments associated with that Feature.
+Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.
+The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;). Abouts and Feature Licenses may be located in any directory of a Download or Module including, but not limited to the following locations:
+
+The top-level (root) directory
+Plug-in and Fragment directories
+Inside Plug-ins and Fragments packaged as JARs
+Sub-directories of the directory named &quot;src&quot; of certain Plug-ins
+Feature directories
+Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license (&quot;Feature Update License&quot;) during the installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or inform you where you can locate them. Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature. Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in that directory.
+
+THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):
+
+Eclipse Distribution License Version 1.0 (available at http://www.eclipse.org/licenses/edl-v1.0.html)
+Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)
+Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)
+Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)
+Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)
+Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.
+
+Use of Provisioning Technology
+
+The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse Update Manager (&quot;Provisioning Technology&quot;) for the purpose of allowing users to install software, documentation, information and/or other materials (collectively &quot;Installable Software&quot;). This capability is provided with the intent of allowing such users to install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html (&quot;Specification&quot;).
+
+You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:
+
+A series of actions may occur (&quot;Provisioning Process&quot;) in which a user may execute the Provisioning Technology on a machine (&quot;Target Machine&quot;) with the intent of installing, extending or updating the functionality of an Eclipse-based product.
+During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be accessed and copied to the Target Machine.
+Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable Software (&quot;Installable Software Agreement&quot;) and such Installable Software Agreement shall be accessed from the Target Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
+Cryptography
+
+Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check the country&apos;s laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted.
+
+Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.
+   </copyright>
+
+   <license url="http://www.eclipse.org/legal/epl-v10.html">
+      Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+&quot;Contribution&quot; means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+&quot;Contributor&quot; means any person or entity that distributes the Program.
+
+&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
+
+&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+   </license>
+
+   <url>
+      <update label="Eclipse UOMo Updates" url="http://www.eclipse.org/uomo/update"/>
+   </url>
+
+   <requires>
+      <import plugin="com.ibm.icu" version="4.2.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.uomo.core" version="0.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.uomo.core" version="0.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.uomo.util" version="0.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.uomo.xml" version="0.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.uomo.units" version="0.6.0" match="greaterOrEqual"/>
+      
+      <import plugin="org.eclipse.core.runtime" version="3.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.osgi" version="3.6.0" match="greaterOrEqual"/>
+      <import plugin="org.eclipse.osgi.services" version="3.2.100" match="greaterOrEqual"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.uomo.business"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.ucum"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.units"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.util"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.uomo.xml"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+
+   <plugin
+         id="org.apache.commons.lang"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.uomo.feature/pom.xml b/features/org.eclipse.uomo.feature/pom.xml
new file mode 100644
index 0000000..e2cf135
--- /dev/null
+++ b/features/org.eclipse.uomo.feature/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo.features</artifactId>
+    	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <packaging>eclipse-feature</packaging>
+  <artifactId>org.eclipse.uomo.feature</artifactId>
+  <name>UOMo Feature</name>
+</project>
diff --git a/features/pom.xml b/features/pom.xml
new file mode 100644
index 0000000..39caacb
--- /dev/null
+++ b/features/pom.xml
@@ -0,0 +1,15 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo</artifactId>
+    	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>org.eclipse.uomo.features</artifactId>
+  <name>Eclipse UOMo Features</name>
+  <packaging>pom</packaging>
+  <modules>
+  	<module>org.eclipse.uomo.feature</module>
+  </modules>
+</project>
\ No newline at end of file
diff --git a/jenkins.build.config.xml b/jenkins.build.config.xml
new file mode 100644
index 0000000..2d46a8c
--- /dev/null
+++ b/jenkins.build.config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--#======================================================================= -->
+<!--# Copyright (c) 2016 - Loetz GmbH&Co.KG                                    -->
+<!--# All rights reserved. This program and the accompanying materials 		 -->
+<!--# are made available under the terms of the Eclipse Public License v1.0  -->
+<!--# which accompanies this distribution, and is available at               -->
+<!--# http://www.eclipse.org/legal/epl-v10.html                              -->
+<!--#                                                                        -->
+<!--# Contributors:                                                          -->
+<!--# Christophe Loetz (Loetz GmbH&Co.KG) - initial API and implementation                           -->
+<!--#======================================================================= -->
+<!--# Module specific parameters for the Jenkins Job 						 -->
+<!--#======================================================================= -->
+
+<jenkins>
+	<jenkins.build.technologystack />
+	<!-- DO NOT EDIT BELOW THIS LINE -->
+        <jenkins.build.dependencies>
+                <jenkins.build.dependency>org.eclipse.osbp.dependencies</jenkins.build.dependency>
+                <jenkins.build.dependency>org.eclipse.osbp.releng.maven</jenkins.build.dependency>
+        </jenkins.build.dependencies>
+</jenkins>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..6a9107e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ======================================================================= 
+    Maven Project Configuration File Eclipse UOMo http://www.eclipse.org/proposals/uomo/ 
+    ======================================================================= -->
+
+<!-- $Id: pom.xml 306 2012-10-29 20:42:27Z werner.keil $ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <!-- <parent> -->
+    <!-- <artifactId>eclipse-parent</artifactId> -->
+    <!-- <groupId>org.eclipse</groupId> -->
+    <!-- <version>1.0.0</version> -->
+    <!-- <relativePath /> -->
+    <!-- </parent> -->
+
+    <!-- <parent> -->
+    <!-- <groupId>org.eclipse.osbp.releng.maven</groupId> -->
+    <!-- <artifactId>org.eclipse.osbp.releng.maven.parent.tycho</artifactId> -->
+    <!-- <version>0.9.0-SNAPSHOT</version> -->
+    <!-- </parent> -->
+
+    <modelVersion>4.0.0</modelVersion>
+    <properties>
+        <osbp.gitrepo.name>${project.groupId}</osbp.gitrepo.name>
+
+        <sourceEncoding>UTF-8</sourceEncoding> <!-- in Maven 3. -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.build.javaVersion>1.6</project.build.javaVersion>
+        <maven.compilerPlugin.version>2.3.2</maven.compilerPlugin.version>
+        <tycho-version>0.18.1</tycho-version>
+
+        <maven.compiler.source>1.6</maven.compiler.source>
+        <maven.compiler.target>1.6</maven.compiler.target>
+        <site.basedir>${project.basedir}</site.basedir>
+    </properties>
+
+    <groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <artifactId>org.eclipse.uomo</artifactId>
+    <version>0.6.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <!-- =========================================================== -->
+    <!-- Developers and Contributors -->
+    <!-- =========================================================== -->
+    <description>UOMo adds Units of Measurement support for IT Systems and Services both to Language and Data.</description>
+    <url>http://www.eclipse.org/uomo/</url>
+    <issueManagement>
+        <system>Bugzilla</system>
+        <url>https://bugs.eclipse.org/bugs/</url>
+    </issueManagement>
+    <inceptionYear>2010</inceptionYear>
+    <developers>
+        <developer>
+            <name>Werner Keil</name>
+            <id>wkeil</id>
+            <organization>Creative Arts &amp; Technologies</organization>
+            <organizationUrl>http://www.catmedia.us</organizationUrl>
+            <email>werner.keil@gmx.net</email>
+            <timezone>0</timezone>
+            <roles>
+                <role>Project Lead</role>
+                <role>Architect</role>
+                <role>Java Developer</role>
+            </roles>
+        </developer>
+        <developer>
+            <name>Chris Senior</name>
+            <id>csenior</id>
+            <email>christopher.senior@gmail.com</email>
+            <organization>Private Individual</organization>
+            <roles>
+                <role>Architect</role>
+                <role>Java Developer</role>
+            </roles>
+        </developer>
+    </developers>
+    <contributors>
+        <contributor>
+            <name>Grahame Grieve</name>
+            <!-- id>grahameg</id -->
+            <email>grahame@healthintersections.com.au</email>
+            <organization>Health Intersections</organization>
+            <organizationUrl>http://www.healthintersections.com.au</organizationUrl>
+            <roles>
+                <role>UCUM Lead</role>
+                <role>Architect</role>
+                <role>Java Developer (inactive)</role>
+            </roles>
+        </contributor>
+
+    </contributors>
+
+    <distributionManagement>
+        <repository>
+            <id>osbp-nexus-release</id>
+            <name>Nexus Release Repository</name>
+            <url>${distribution.repository.release.url}</url>
+        </repository>
+        <snapshotRepository>
+            <id>osbp-nexus-snapshots</id>
+            <name>Sonatype Nexus Snapshots</name>
+            <url>${distribution.repository.snapshot.url}</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+    <scm>
+        <url>http://git.eclipse.org/c/uomo/org.eclipse.uomo.git/</url>
+    </scm>
+    <organization>
+        <name>Eclipse Foundation</name>
+        <url>http://www.eclipse.org</url>
+    </organization>
+    <modules>
+        <module>bundles</module>
+        <module>features</module>
+        <!-- <module>examples</module> -->
+        <module>releng</module>
+    </modules>
+
+    <profiles>
+        <profile>
+            <id>platform.default</id>
+            <activation>
+                <property>
+                    <name>!osbp.build.eclipse.platform.name</name>
+                </property>
+            </activation>
+            <properties>
+                <osbp.build.eclipse.platform.name>luna</osbp.build.eclipse.platform.name>
+                <osbp.build.eclipse.platform.p2.url>http://download.eclipse.org/releases/luna</osbp.build.eclipse.platform.p2.url>
+            </properties>
+        </profile>
+        <profile>
+            <id>platform.luna</id>
+            <activation>
+                <property>
+                    <name>osbp.build.eclipse.platform.name</name>
+                    <value>luna</value>
+                </property>
+            </activation>
+            <properties>
+                <osbp.build.eclipse.platform.name>luna</osbp.build.eclipse.platform.name>
+                <osbp.build.eclipse.platform.p2.url>http://download.eclipse.org/releases/luna</osbp.build.eclipse.platform.p2.url>
+            </properties>
+        </profile>
+    </profiles>
+
+    
+    <!-- ==================================================== -->
+    <!-- Repositories. This is where Maven looks for dependencies. The Maven 
+        repository is implicit and doesn't need to be specified. -->
+    <!-- ==================================================== -->
+    <repositories>
+
+        <repository>
+            <id>eclipse.p2</id>
+            <url>${osbp.build.eclipse.platform.p2.url}</url>
+            <layout>p2</layout>
+        </repository>
+
+        <repository>
+            <id>central</id>
+            <name>Central Eclipse.org Nexus</name>
+            <url>http://central.maven.org/maven2/</url>
+        </repository>
+
+        <!-- <repository> -->
+        <!-- <id>eclipse-public</id> not working at the moment ml/06.05.2016 -->
+        <!-- <name>Public Eclipse.org Nexus</name> -->
+        <!-- <url>http://maven.eclipse.org/nexus/content/groups/public/</url> -->
+        <!-- </repository> -->
+
+        <repository>
+            <id>atlassian</id>
+            <url>https://maven.atlassian.com/repository/public</url>
+            <snapshots>
+                <enabled>true</enabled>
+                <updatePolicy>never</updatePolicy>
+                <checksumPolicy>warn</checksumPolicy>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+                <checksumPolicy>warn</checksumPolicy>
+            </releases>
+        </repository>
+
+        <repository>
+            <id>maven-geotoolkit.org</id>
+            <name>GeoToolkit Repository for Maven</name>
+            <url>http://maven.geotoolkit.org/</url>
+        </repository>
+    </repositories>
+    
+    
+    <!-- ======================================================= -->
+    <!-- Build Settings -->
+    <!-- ======================================================= -->
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.5</version>
+                <executions>
+                    <execution>
+                        <id>copy-sitedescriptor</id>
+                        <!-- fetch site.xml before creating site documentation -->
+                        <phase>pre-site</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${basedir}/src/site/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${site.basedir}/src/site/</directory>
+                                    <includes>
+                                        <include>**/site.xml</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <!-- This sets up the target platform in PDE terms The version 
+                    of Eclipse that the source will be built against -->
+                <groupId>org.eclipse.tycho</groupId>
+                <artifactId>target-platform-configuration</artifactId>
+                <version>${tycho-version}</version>
+                <configuration>
+                    <resolver>p2</resolver>
+                    <target>
+                        <artifact>
+                            <groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+                            <artifactId>org.eclipse.uomo.target</artifactId>
+                            <version>0.6.0-SNAPSHOT</version>
+                            <classifier>indigo</classifier>
+                        </artifact>
+                    </target>
+                    <ignoreTychoRepositories>true</ignoreTychoRepositories>
+                    <environments>
+                        <environment>
+                            <os>win32</os>
+                            <ws>win32</ws>
+                            <arch>x86</arch>
+                        </environment>
+                        <environment>
+                            <os>linux</os>
+                            <ws>gtk</ws>
+                            <arch>x86</arch>
+                        </environment>
+                    </environments>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.tycho</groupId>
+                <artifactId>tycho-maven-plugin</artifactId>
+                <version>${tycho-version}</version>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.4</version>
+            </plugin>
+            <plugin>
+                <groupId>org.sonatype.tycho</groupId>
+                <artifactId>maven-osgi-packaging-plugin</artifactId>
+                <version>0.11.1</version>
+<!--                 <version>${tycho-version}</version> -->
+                <configuration>
+                    <archive>
+                        <addMavenDescriptor>false</addMavenDescriptor>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+
+    </build>
+</project>
\ No newline at end of file
diff --git a/releng/.project b/releng/.project
new file mode 100644
index 0000000..75a9c24
--- /dev/null
+++ b/releng/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.releng</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/releng/Maven Clean Install.launch b/releng/Maven Clean Install.launch
new file mode 100644
index 0000000..ddc3626
--- /dev/null
+++ b/releng/Maven Clean Install.launch
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dmaven.test.skip=true"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.uomo}"/>
+</launchConfiguration>
diff --git a/releng/Maven Clean Package.launch b/releng/Maven Clean Package.launch
new file mode 100644
index 0000000..d2a0f15
--- /dev/null
+++ b/releng/Maven Clean Package.launch
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="clean package"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dmaven.test.skip=true"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.uomo}"/>
+</launchConfiguration>
diff --git a/releng/Maven Install.launch b/releng/Maven Install.launch
new file mode 100644
index 0000000..01673ec
--- /dev/null
+++ b/releng/Maven Install.launch
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
+<stringAttribute key="M2_GOALS" value="install"/>
+<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
+<booleanAttribute key="M2_OFFLINE" value="false"/>
+<stringAttribute key="M2_PROFILES" value=""/>
+<listAttribute key="M2_PROPERTIES"/>
+<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
+<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
+<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
+<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.uomo}"/>
+</launchConfiguration>
diff --git a/releng/eclipse-repository/.project b/releng/eclipse-repository/.project
new file mode 100644
index 0000000..15d302d
--- /dev/null
+++ b/releng/eclipse-repository/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>eclipse-repository</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/releng/eclipse-repository/category.xml b/releng/eclipse-repository/category.xml
new file mode 100644
index 0000000..9bf863b
--- /dev/null
+++ b/releng/eclipse-repository/category.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/org.eclipse.uomo.feature_0.6.0.jar" id="org.eclipse.uomo.feature" version="0.6.0">
+   	  <category name="uomo-category"/>
+   </feature>
+   <category-def name="uomo-category" label="Units of Measurement (UOMo)">
+      <description>
+         UOMo adds Units of Measurement support for IT Systems and Services both to Language and Data.
+      </description>
+   </category-def>
+</site>
diff --git a/releng/eclipse-repository/pom.xml b/releng/eclipse-repository/pom.xml
new file mode 100644
index 0000000..8b39567
--- /dev/null
+++ b/releng/eclipse-repository/pom.xml
@@ -0,0 +1,13 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>org.eclipse.uomo.releng</artifactId>
+    	<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+    <version>0.6.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>eclipse-repository</artifactId>
+  <name>Eclipse UOMo Repository</name>
+  <packaging>eclipse-repository</packaging>
+  
+</project>
\ No newline at end of file
diff --git a/releng/org.eclipse.uomo.target/.gitignore b/releng/org.eclipse.uomo.target/.gitignore
new file mode 100644
index 0000000..40a85ff
--- /dev/null
+++ b/releng/org.eclipse.uomo.target/.gitignore
@@ -0,0 +1 @@
+/.settings
diff --git a/releng/org.eclipse.uomo.target/.project b/releng/org.eclipse.uomo.target/.project
new file mode 100644
index 0000000..f2d91c3
--- /dev/null
+++ b/releng/org.eclipse.uomo.target/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.uomo.target</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/releng/org.eclipse.uomo.target/indigo.target b/releng/org.eclipse.uomo.target/indigo.target
new file mode 100644
index 0000000..5188992
--- /dev/null
+++ b/releng/org.eclipse.uomo.target/indigo.target
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde version="3.8"?><target name="Target Platform for the Eclipse UOMo project" sequenceNumber="23">
+<locations>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.equinox.sdk.feature.group" version="3.7.1.R37x_v20110907-7M7W8i8eNV4WsRkue-4Vq4J6pCyW"/>
+<repository location="http://download.eclipse.org/releases/indigo/"/>
+</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.apache.commons.lang" version="2.6.0.v201205030909"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository/"/>
+</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.junit" version="4.10.0.v4_10_0_v20120426-0900"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository/"/>
+</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.apache.xerces" version="2.9.0.v201101211617"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20120526062928/repository/"/>
+</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="com.ibm.icu" version="50.1.1.v201304230130"/>
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20130517111416/repository/"/>
+</location>
+</locations>
+</target>
diff --git a/releng/org.eclipse.uomo.target/pom.xml b/releng/org.eclipse.uomo.target/pom.xml
new file mode 100644
index 0000000..7eea219
--- /dev/null
+++ b/releng/org.eclipse.uomo.target/pom.xml
@@ -0,0 +1,13 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>org.eclipse.uomo.releng</artifactId>
+		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+		<version>0.6.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+	<artifactId>org.eclipse.uomo.target</artifactId>
+	<name>Eclipse UOMo Target Definition</name>
+    <packaging>pom</packaging>
+</project>
\ No newline at end of file
diff --git a/releng/pom.xml b/releng/pom.xml
new file mode 100644
index 0000000..7751b25
--- /dev/null
+++ b/releng/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+    <parent>
+  		<groupId>org.eclipse.osbp.fork.eclipse.uomo</groupId>
+  	<artifactId>org.eclipse.uomo</artifactId>
+  	<version>0.6.0-SNAPSHOT</version>
+  	<relativePath>..</relativePath>
+    </parent>
+  <artifactId>org.eclipse.uomo.releng</artifactId>
+  <name>Eclipse UOMo</name>
+  <packaging>pom</packaging>
+  <modules>
+  	<module>org.eclipse.uomo.target</module>
+<!--  	<module>eclipse-repository</module> -->
+  </modules>
+</project>
\ No newline at end of file