First contribution of NoSql entity generation code as per bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=393938.

Also renamed org.eclipse.persistence.tools.gen to org.eclipse.persistence.tools.gen.db and org.eclipse.persistence.tools.gen.db to org.eclipse.persistence.tools.db to align with new naming scheme  introduced with the no sql contribution.

Peer review by Neil Hauge.
diff --git a/tools/org.eclipse.persistence.tools.gen/.classpath b/tools/org.eclipse.persistence.tools.db/.classpath
similarity index 78%
rename from tools/org.eclipse.persistence.tools.gen/.classpath
rename to tools/org.eclipse.persistence.tools.db/.classpath
index 32c7e58..0b9079a 100644
--- a/tools/org.eclipse.persistence.tools.gen/.classpath
+++ b/tools/org.eclipse.persistence.tools.db/.classpath
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="resource/templates/xml_entities"/>
-	<classpathentry kind="src" path="resource/property_files"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
 		<attributes>
 			<attribute name="owner.project.facets" value="java"/>
diff --git a/tools/org.eclipse.persistence.tools.gen/.project b/tools/org.eclipse.persistence.tools.db/.project
similarity index 95%
rename from tools/org.eclipse.persistence.tools.gen/.project
rename to tools/org.eclipse.persistence.tools.db/.project
index 831ed03..64a9a2a 100644
--- a/tools/org.eclipse.persistence.tools.gen/.project
+++ b/tools/org.eclipse.persistence.tools.db/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>org.eclipse.persistence.tools.gen</name>
+	<name>org.eclipse.persistence.tools.db</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.resources.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.core.resources.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.resources.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.core.resources.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.runtime.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.core.runtime.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.runtime.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.core.runtime.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.jdt.core.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.jdt.core.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.jdt.core.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.jdt.core.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.ltk.core.refactoring.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.ltk.core.refactoring.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.ltk.core.refactoring.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.ltk.core.refactoring.prefs
diff --git a/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.component b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..5bdf470
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="org.eclipse.persistence.tools.db">
+        <wb-resource deploy-path="/" source-path="/src"/>
+    </wb-module>
+</project-modules>
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.project.facet.core.xml
similarity index 99%
rename from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.project.facet.core.xml
index 2d6935f..fd68f7e 100644
--- a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <faceted-project>
-  <fixed facet="jst.utility"/>
   <fixed facet="java"/>
-  <installed facet="jst.utility" version="1.0"/>
+  <fixed facet="jst.utility"/>
   <installed facet="java" version="1.6"/>
+  <installed facet="jst.utility" version="1.0"/>
 </faceted-project>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.xsl.core.prefs b/tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.xsl.core.prefs
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.xsl.core.prefs
rename to tools/org.eclipse.persistence.tools.db/.settings/org.eclipse.wst.xsl.core.prefs
diff --git a/tools/org.eclipse.persistence.tools.db/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.db/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..7824848
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Export-Package: org.eclipse.persistence.tools.db,
+ org.eclipse.persistence.tools.db.driver,
+ org.eclipse.persistence.tools.db.model,
+ org.eclipse.persistence.tools.db.model.handles,
+ org.eclipse.persistence.tools.db.model.platformsmodel,
+ org.eclipse.persistence.tools.db.model.spi,
+ org.eclipse.persistence.tools.db.model.spi.jdbc,
+ platforms
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.persistence.tools.utility;bundle-version="2.5.0",
+ org.eclipse.persistence.tools.gen.db;bundle-version="2.5.0",
+ org.eclipse.persistence.core;bundle-version="2.4.0"
+Bundle-SymbolicName: org.eclipse.persistence.tools.db
+Bundle-Name: EclipseLink Tools Db
+Bundle-Vendor: Eclipse.org - EclipseLink Project
+Bundle-Version: 2.5.0.qualifier
+Bundle-ManifestVersion: 2
+Import-Package: org.w3c.dom;resolution:=optional
diff --git a/tools/org.eclipse.persistence.tools.db/build.properties b/tools/org.eclipse.persistence.tools.db/build.properties
new file mode 100644
index 0000000..b107977
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/build.properties
@@ -0,0 +1,3 @@
+source.. = src/
+bin.includes = META-INF/,\
+               .
diff --git a/tools/org.eclipse.persistence.tools.gen/pom.xml b/tools/org.eclipse.persistence.tools.db/pom.xml
similarity index 86%
copy from tools/org.eclipse.persistence.tools.gen/pom.xml
copy to tools/org.eclipse.persistence.tools.db/pom.xml
index ffc11fc..62d58d4 100644
--- a/tools/org.eclipse.persistence.tools.gen/pom.xml
+++ b/tools/org.eclipse.persistence.tools.db/pom.xml
@@ -3,9 +3,9 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <modelVersion>4.0.0</modelVersion>
 
-    <name>EclipseLink Tools Gen</name>
+    <name>EclipseLink Tools Gen DB</name>
     <groupId>org.eclipse.persistence</groupId>
-    <artifactId>org.eclipse.persistence.tools.gen</artifactId>
+    <artifactId>org.eclipse.persistence.tools.db</artifactId>
     <version>2.5.0-SNAPSHOT</version>
     <packaging>eclipse-plugin</packaging>
 
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumn.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumn.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumn.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumnPair.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumnPair.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkColumnPair.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkConnectionProfile.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkConnectionProfile.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkConnectionProfile.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkConnectionProfile.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkDatabase.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkForeignKey.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkSchema.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/EclipseLinkTable.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/AbstractWorkbenchDriverAdapter.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/CatalogStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/CatalogStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/CatalogStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/CatalogStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/DB2.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/DB2.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/DB2.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/DB2.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Derby.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Derby.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Derby.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Derby.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/FauxCatalogStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/FauxCatalogStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/FauxCatalogStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/FauxCatalogStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/FoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/FoldingStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/FoldingStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/FoldingStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/HSQLDB.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/HSQLDB.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/HSQLDB.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/HSQLDB.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Informix.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Informix.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Informix.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Informix.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/LowerCaseFoldingStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/MaxDB.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MaxDB.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/MaxDB.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MaxDB.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/MySQL.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/NoCatalogStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/NoCatalogStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/NoCatalogStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/NoCatalogStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/NonFoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/NonFoldingStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/NonFoldingStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/NonFoldingStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Oracle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Oracle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Oracle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Oracle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/PostgreSQL.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/PostgreSQL.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/PostgreSQL.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/PostgreSQL.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SQLServer.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/SimpleCatalogStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SimpleCatalogStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/SimpleCatalogStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/SimpleCatalogStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Sybase.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Unknown.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Unknown.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/Unknown.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/Unknown.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/UpperCaseFoldingStrategy.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapter.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapter.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapter.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapter.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterFactory.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterFactory.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterFactory.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterManager.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterManager.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterManager.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/driver/WorkbenchDriverAdapterManager.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/DatabaseTypeHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/DatabaseTypeHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/DatabaseTypeHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/DatabaseTypeHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELColumn.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELColumn.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELColumn.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELColumnPair.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELColumnPair.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELColumnPair.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELDatabase.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpec.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpecHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpecHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpecHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELLoginSpecHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELModel.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELNode.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELNode.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELNode.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELNode.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELReference.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELReference.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/ELTable.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/NodeModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/NodeModel.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/NodeModel.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/NodeModel.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnPairHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnPairHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnPairHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWColumnPairHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWReferenceHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWReferenceHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWReferenceHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWReferenceHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWTableHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWTableHandle.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/handles/MWTableHandle.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/handles/MWTableHandle.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/CorruptXMLException.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/CorruptXMLException.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/CorruptXMLException.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/CorruptXMLException.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatform.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabasePlatformRepository.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/DatabaseType.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCType.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeRepository.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclaration.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalColumn.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalColumn.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalColumn.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabase.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabase.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabase.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabaseFactory.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabaseFactory.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalDatabaseFactory.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKey.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKey.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKey.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKeyColumnPair.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKeyColumnPair.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalForeignKeyColumnPair.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTable.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTable.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTable.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTableDescription.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTableDescription.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/ExternalTableDescription.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/TableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/TableDescription.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/TableDescription.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/TableDescription.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalColumn.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabase.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalDatabaseFactory.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKey.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTable.java
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
rename to tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/model/spi/jdbc/JDBCExternalTableDescription.java
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/DatabaseTypeHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/DatabaseTypeHandle.java
new file mode 100644
index 0000000..2535cee
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/DatabaseTypeHandle.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabaseType;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * This handle is a bit different from the other handles. It references an object that is completely
+ * outside of the project and is only used by database fields.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+final class DatabaseTypeHandle extends MWHandle {
+
+	/**
+	 * This is the actual database type.
+	 * It is built from the database type name, below.
+	 */
+	private volatile DatabaseType databaseType;
+
+	/**
+	 * The database type name is transient. It
+	 * is used only to hold its value until #postProjectBuild()
+	 * is called and we can resolve the actual database type.
+	 * We do not keep it in synch with the database type itself because
+	 * we cannot know when the database type has been renamed etc.
+	 */
+	private volatile String databaseTypeName;
+
+	// ********** constructors **********
+
+	DatabaseTypeHandle(ELColumn parent) {
+		// database types are never removed
+		super(parent, NodeReferenceScrubber.NULL_INSTANCE);
+	}
+
+
+	// ********** instance methods **********
+
+	DatabaseType getDatabaseType() {
+		return this.databaseType;
+	}
+
+	void setDatabaseType(DatabaseType databaseType) {
+		this.databaseType = databaseType;
+	}
+
+	@Override
+	protected Node node() {
+		return getDatabaseType();
+	}
+
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.databaseType == null) {
+			sb.append("null");
+		} else {
+			this.databaseType.toString(sb);
+		}
+	}
+
+
+	// ********** TopLink methods **********
+
+	String getDatabaseTypeNameForTopLink() {
+		return (this.databaseType == null) ? null : this.databaseType.getName();
+	}
+
+	void setDatabaseTypeNameForTopLink(String name) {
+		this.databaseTypeName = name;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java
new file mode 100644
index 0000000..0fce922
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumn.java
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.util.List;
+
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabaseType;
+import org.eclipse.persistence.tools.db.relational.platformsmodel.JavaTypeDeclaration;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELColumn extends ELModel {
+
+	/** the name should never be null or empty */
+	private volatile String name;
+		public static final String NAME_PROPERTY = "name";
+		public static final String QUALIFIED_NAME_PROPERTY = "qualifiedName";
+
+	/** the database type should never be null */
+	private DatabaseTypeHandle databaseTypeHandle;	// pseudo-final
+		public static final String DATABASE_TYPE_PROPERTY = "databaseType";
+
+	private volatile int size;
+		public static final String SIZE_PROPERTY = "size";
+
+	/** sub-size is used for scale on numeric types */
+	private volatile int subSize;
+		public static final String SUB_SIZE_PROPERTY = "subSize";
+
+	private volatile boolean allowsNull;
+		public static final String ALLOWS_NULL_PROPERTY = "allowsNull";
+
+	private volatile boolean unique;
+		public static final String UNIQUE_PROPERTY = "unique";
+
+	/** this is typically short-hand for 'NOT NULL' and 'UNIQUE' */
+	private volatile boolean primaryKey;
+		public static final String PRIMARY_KEY_PROPERTY = "primaryKey";
+
+	/** SQL Server variants allow the IDENTITY clause */
+	private volatile boolean identity;
+		public static final String IDENTITY_PROPERTY = "identity";
+
+	// ********** static methods **********
+
+	/**
+	 * Parse the table name from a possibly "qualified" column name:
+	 * "ACTG.EMPLOYEE.F_NAME" -> "ACCTG.EMPLOYEE"
+	 * "ACTG..F_NAME" -> "ACCTG.."
+	 * "EMPLOYEE.F_NAME" -> "EMPLOYEE"
+	 * "F_NAME" -> ""
+	 */
+	public static String parseTableNameFromQualifiedName(String name) {
+		int index = name.lastIndexOf('.');
+		if (index == -1) {
+			return StringTools.EMPTY_STRING;
+		}
+		return name.substring(0, index);
+	}
+
+	/**
+	 * Parse the column name from a possibly "qualified" column name:
+	 * "ACCT.EMPLOYEE.F_NAME" -> "F_NAME"
+	 * "ACCT..F_NAME" -> "F_NAME"
+	 * "EMPLOYEE.F_NAME" -> "F_NAME"
+	 * "F_NAME" -> "F_NAME"
+	 */
+	public static String parseColumnNameFromQualifiedName(String name) {
+		int index = name.lastIndexOf('.');
+		if (index == -1) {
+			return name;
+		}
+		return name.substring(index + 1);
+	}
+
+	public static boolean nameIsQualified(String columnName) {
+		return columnName.indexOf(".") != -1;
+	}
+
+
+	// ********** constructors **********
+
+	ELColumn(ELTable table, String name) {
+		super(table);
+		this.name = name;
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * the database type handle is not mapped directly
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.databaseTypeHandle = new DatabaseTypeHandle(this);
+	}
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		DatabaseType dbType = this.defaultDatabaseType();
+		this.databaseTypeHandle.setDatabaseType(dbType);
+		this.size = dbType.requiresSize() ? dbType.getInitialSize() : 0;
+		this.subSize = 0;
+		this.allowsNull = dbType.allowsNull();
+		this.unique = false;
+		this.primaryKey = false;
+		this.identity = false;
+	}
+
+
+	// ********** accessors **********
+
+	public ELTable getTable() {
+		return this.getParent();
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.getTable().checkColumnName(name);
+		Object old = this.name;
+		this.name = name;
+		if (this.attributeValueHasChanged(old, name)) {
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+			this.qualifiedNameChanged();
+		}
+	}
+
+	void qualifiedNameChanged() {
+		String qName = this.qualifiedName();
+		this.firePropertyChanged(QUALIFIED_NAME_PROPERTY, qName);
+	}
+
+	public DatabaseType getDatabaseType() {
+		return this.databaseTypeHandle.getDatabaseType();
+	}
+
+	public void setDatabaseType(DatabaseType databaseType) {
+		if (databaseType == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.databaseTypeHandle.getDatabaseType();
+		this.databaseTypeHandle.setDatabaseType(databaseType);
+		this.firePropertyChanged(DATABASE_TYPE_PROPERTY, old, databaseType);
+		// align various settings with the new database type
+		if (this.attributeValueHasChanged(old, databaseType)) {
+			this.synchronizeWithNewDatabaseType();
+		}
+	}
+
+	public int getSize() {
+		return this.size;
+	}
+
+	public void setSize(int size) {
+		if (( ! this.getDatabaseType().allowsSize()) && (size != 0)) {
+			throw new IllegalArgumentException("size must be 0 when size is not allowed");
+		}
+		int old = this.size;
+		this.size = size;
+		this.firePropertyChanged(SIZE_PROPERTY, old, size);
+	}
+
+	public int getSubSize() {
+		return this.subSize;
+	}
+
+	public void setSubSize(int subSize) {
+		if (( ! this.getDatabaseType().allowsSubSize()) && (subSize != 0)) {
+			throw new IllegalArgumentException("sub-size must be 0 when sub-size is not allowed");
+		}
+		int old = this.subSize;
+		this.subSize = subSize;
+		this.firePropertyChanged(SUB_SIZE_PROPERTY, old, subSize);
+	}
+
+	public boolean allowsNull() {
+		return this.allowsNull;
+	}
+
+	public void setAllowsNull(boolean allowsNull) {
+		if (( ! this.getDatabaseType().allowsNull()) && (allowsNull)) {
+			throw new IllegalArgumentException("allows null must be false when allows null is not allowed");
+		}
+		boolean old = this.allowsNull;
+		this.allowsNull = allowsNull;
+		this.firePropertyChanged(ALLOWS_NULL_PROPERTY, old, allowsNull);
+		if (allowsNull) {
+			this.setPrimaryKey(false);
+			this.setIdentity(false);
+		}
+	}
+
+	public boolean isUnique() {
+		return this.unique;
+	}
+
+	public void setUnique(boolean unique) {
+		boolean old = this.unique;
+		this.unique = unique;
+		this.firePropertyChanged(UNIQUE_PROPERTY, old, unique);
+		if ( ! unique) {
+			this.setPrimaryKey(false);
+		}
+	}
+
+	public boolean isPrimaryKey() {
+		return this.primaryKey;
+	}
+
+	/**
+	 * primary key is typically equivalent to
+	 * 'NOT NULL' and 'UNIQUE'
+	 */
+	public void setPrimaryKey(boolean primaryKey) {
+		boolean old = this.primaryKey;
+		this.primaryKey = primaryKey;
+		this.firePropertyChanged(PRIMARY_KEY_PROPERTY, old, primaryKey);
+		if (primaryKey) {
+			this.setAllowsNull(false);
+			this.setUnique(true);
+		}
+	}
+
+	public boolean isIdentity() {
+		return this.identity;
+	}
+
+	/**
+	 * 'IDENTITY' requires 'NOT NULL'
+	 */
+	public void setIdentity(boolean identity) {
+		if (( ! this.supportsIdentityClause()) && (identity)) {
+			throw new IllegalArgumentException("the current platform does not support the IDENTITY clause");
+		}
+		boolean old = this.identity;
+		this.identity = identity;
+		this.firePropertyChanged(IDENTITY_PROPERTY, old, identity);
+		if (identity) {
+			this.setAllowsNull(false);
+		}
+	}
+
+
+	// ********** queries **********
+
+	public DatabasePlatform databasePlatform() {
+		 return this.getTable().databasePlatform();
+	}
+
+	public String qualifiedName() {
+		return this.getTable().qualifiedName() + '.' + this.getName();
+	}
+
+	/**
+	 * this is the initial value of our database type
+	 */
+	private DatabaseType defaultDatabaseType() {
+		return this.databasePlatform().defaultDatabaseType();
+	}
+
+	/**
+	 * Returns the Java type declaration corresponding to the column's database type;
+	 * this is used to generate instance variables from database columns when
+	 * generating classes from tables
+	 */
+	public JavaTypeDeclaration javaTypeDeclaration() {
+		return this.getDatabaseType().javaTypeDeclaration();
+	}
+
+	/**
+	 * Returns whether the column can be defined with an IDENTITY
+	 * clause (SQL Server variants only)
+	 */
+	public boolean supportsIdentityClause() {
+		return this.getDatabase().supportsIdentityClause();
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void addChildrenTo(List<Node> children) {
+		super.addChildrenTo(children);
+		children.add(this.databaseTypeHandle);
+	}
+
+	@Override
+	public ELTable getParent() {
+		return (ELTable)super.getParent();
+	}
+
+	public ELDatabase getDatabase() {
+		return getParent().getParent();
+	}
+
+	/**
+	 * replace our database type (from our old database platform) with
+	 * a database type from our new database platform that is a reasonable
+	 * match
+	 */
+	void databasePlatformChanged() {
+		this.setDatabaseType(this.databasePlatform().databaseTypeFor(this.getDatabaseType()));
+	}
+
+	private void synchronizeWithNewDatabaseType() {
+		DatabaseType dbType = this.getDatabaseType();
+
+		// synchronize size/sub-size
+		if (dbType.allowsSize()) {
+			if (dbType.allowsSubSize()) {
+				// leave sub-size unchanged - it will be zero unless we are converting
+				// from one numeric type to another numeric type and a "scale" was specified
+			} else {
+				this.setSubSize(0);
+			}
+			if (dbType.requiresSize()) {
+				if (this.size == 0) {
+					this.setSize(dbType.getInitialSize());
+				} else {
+					// take the previously-assigned size
+				}
+			} else {
+				if (this.subSize == 0) {
+					// if size is not required and a sub-size was not specified,
+					// we probably want to clear out size: VARCHAR2(20) => NUMBER
+					this.setSize(0);
+				} else {
+					// we will only get here when converting from one numeric type
+					// to another numeric type and a "scale" was specified - keep
+					// the same size/sub-size combination
+				}
+			}
+		} else {
+			this.setSize(0);
+			this.setSubSize(0);
+		}
+
+		// synchronize allows null
+		if (dbType.allowsNull()) {
+			// leave allows null unchanged
+		} else {
+			this.setAllowsNull(false);
+		}
+
+		// IDENTITY
+		if (dbType.getPlatform().supportsIdentityClause()) {
+			// leave identity unchanged
+		} else {
+			this.setIdentity(false);
+		}
+	}
+
+	void copySettingsFrom(ELColumn original) {
+		this.setDatabaseType(original.getDatabaseType());
+		this.setSize(original.getSize());
+		this.setSubSize(original.getSubSize());
+		this.setAllowsNull(original.allowsNull());
+		this.setUnique(original.isUnique());
+		this.setPrimaryKey(original.isPrimaryKey());
+		this.setIdentity(original.isIdentity());
+	}
+
+	// ********** DataField implementation **********
+
+	/**
+	 * used by UI components common to O-R and O-X
+	 * (mappings, locking policy, etc.)
+	 */
+	public String fieldName() {
+		return this.qualifiedName();
+	}
+
+
+	// ********** importing/refreshing **********
+
+	/**
+	 * refresh with the data from the specified "external" column
+	 */
+	void refresh(ExternalColumn externalColumn) {
+		this.setDatabaseType(this.databaseTypeFrom(externalColumn));
+		this.setSize(this.sizeFrom(externalColumn));
+		this.setSubSize(this.subSizeFrom(externalColumn));
+		this.setAllowsNull(this.allowsNullFrom(externalColumn));
+		this.setPrimaryKey(externalColumn.isPrimaryKey());
+		// leave 'unique' unchanged - I don't think we can get it from the database
+		// 'primaryKey' will be set later by our parent table
+	}
+
+	/**
+	 * first try to get the platform-specific datatype;
+	 * if that fails, get the platform-specific datatype most
+	 * closely associated with the JDBC type;
+	 * if that fails, get the default datatype
+	 */
+	private DatabaseType databaseTypeFrom(ExternalColumn externalColumn) {
+		try {
+			return this.databasePlatform().databaseTypeNamed(externalColumn.getTypeName());
+		} catch (IllegalArgumentException ex) {
+			return this.databaseTypeFromJDBCTypeFrom(externalColumn);
+		}
+	}
+
+	private DatabaseType databaseTypeFromJDBCTypeFrom(ExternalColumn externalColumn) {
+		try {
+			return this.databasePlatform().databaseTypeForJDBCTypeCode(externalColumn.getJDBCTypeCode());
+		} catch (Exception ex) {
+			// defensive - when all else fails, use the default type
+			return this.databasePlatform().defaultDatabaseType();
+		}
+	}
+
+	private int sizeFrom(ExternalColumn externalColumn) {
+		if ( ! this.getDatabaseType().allowsSize()) {
+			// ignore the size in the "external" column - it cannot be used in the column's declaration
+			return 0;
+		}
+		return externalColumn.getSize();
+	}
+
+	private int subSizeFrom(ExternalColumn externalColumn) {
+		if ( ! this.getDatabaseType().allowsSubSize()) {
+			// ignore the sub-size in the "external" column - it cannot be used in the column's declaration
+			return 0;
+		}
+		return externalColumn.getScale();
+	}
+
+	private boolean allowsNullFrom(ExternalColumn externalColumn) {
+		if ( ! this.getDatabaseType().allowsNull()) {
+			// ignore the flag in the "external" column - the column cannot be null, given its current datatype
+			return false;
+		}
+		return externalColumn.isNullable();
+	}
+
+	// ********** displaying and printing **********
+
+	@Override
+	public String displayString() {
+		return this.qualifiedName();
+	}
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.qualifiedName());
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java
new file mode 100644
index 0000000..fe4cb9e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELColumnPair.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.util.List;
+
+import org.eclipse.persistence.tools.db.relational.handles.MWColumnHandle;
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle.NodeReferenceScrubber;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * Simple class that pairs a source column and a target column for a reference.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELColumnPair extends ELModel {
+
+	private MWColumnHandle sourceColumnHandle;
+		public static final String SOURCE_COLUMN_PROPERTY = "sourceColumn";
+
+	private MWColumnHandle targetColumnHandle;
+		public static final String TARGET_COLUMN_PROPERTY = "targetColumn";
+
+	// ********** constructors **********
+
+	ELColumnPair(ELReference parent, ELColumn sourceColumn, ELColumn targetColumn) {
+		super(parent);
+		this.sourceColumnHandle.setColumn(sourceColumn);
+		this.targetColumnHandle.setColumn(targetColumn);
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		this.sourceColumnHandle = new MWColumnHandle(this, this.buildSourceColumnScrubber());
+		this.targetColumnHandle = new MWColumnHandle(this, this.buildTargetColumnScrubber());
+	}
+
+
+	// ********** accessors **********
+
+	public ELReference getReference() {
+		return (ELReference) this.getParent();
+	}
+
+	public ELColumn getSourceColumn() {
+		return this.sourceColumnHandle.getColumn();
+	}
+
+	public void setSourceColumn(ELColumn sourceColumn) {
+		if ((sourceColumn != null) && (sourceColumn.getTable() != this.getReference().getSourceTable())) {
+			throw new IllegalArgumentException();
+		}
+		Object old = this.sourceColumnHandle.getColumn();
+		this.sourceColumnHandle.setColumn(sourceColumn);
+		this.firePropertyChanged(SOURCE_COLUMN_PROPERTY, old, sourceColumn);
+	}
+
+	public ELColumn getTargetColumn() {
+		return this.targetColumnHandle.getColumn();
+	}
+
+	public void setTargetColumn(ELColumn targetColumn) {
+		if ((targetColumn != null) && (targetColumn.getTable() != this.getReference().getTargetTable())) {
+			throw new IllegalArgumentException();
+		}
+		Object old = this.targetColumnHandle.getColumn();
+		this.targetColumnHandle.setColumn(targetColumn);
+		this.firePropertyChanged(TARGET_COLUMN_PROPERTY, old, targetColumn);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * the pair's name is calculated from the two column names
+	 */
+	public String getName() {
+		StringBuffer sb = new StringBuffer(200);
+		this.appendColumn(sb, this.getSourceColumn());
+		sb.append('=');
+		this.appendColumn(sb, this.getTargetColumn());
+		return sb.toString();
+	}
+
+	private void appendColumn(StringBuffer sb, ELColumn column) {
+		if (column != null) {
+			sb.append(column.qualifiedName());
+		}
+	}
+
+	/**
+	 * Returns whether the column pair matches up the specified columns
+	 */
+	boolean pairs(ELColumn sourceColumn, ELColumn targetColumn) {
+		return (this.getSourceColumn() == sourceColumn) &&
+			(this.getTargetColumn() == targetColumn);
+	}
+
+	public ELTable sourceTable() {
+		return this.tableFrom(this.getSourceColumn());
+	}
+
+	public ELTable targetTable() {
+		return this.tableFrom(this.getTargetColumn());
+	}
+
+	private ELTable tableFrom(ELColumn column) {
+		return (column == null) ? null : column.getTable();
+	}
+
+
+	// ********** behavior **********
+
+	public void setSourceAndTargetColumns(ELColumn sourceColumn, ELColumn targetColumn) {
+		this.setSourceColumn(sourceColumn);
+		this.setTargetColumn(targetColumn);
+	}
+
+	// ********** containment hierarchy **********
+
+	@Override
+	protected void addChildrenTo(List<Node> children) {
+		super.addChildrenTo(children);
+		children.add(this.sourceColumnHandle);
+		children.add(this.targetColumnHandle);
+	}
+
+	private NodeReferenceScrubber buildSourceColumnScrubber() {
+		return new NodeReferenceScrubber() {
+			@Override
+			public void nodeReferenceRemoved(Node node, MWHandle handle) {
+				ELColumnPair.this.setSourceColumn(null);
+			}
+			@Override
+			public String toString() {
+				return "MWColumnPair.buildSourceColumnScrubber()";
+			}
+		};
+	}
+
+	private NodeReferenceScrubber buildTargetColumnScrubber() {
+		return new NodeReferenceScrubber() {
+			@Override
+			public void nodeReferenceRemoved(Node node, MWHandle handle) {
+				ELColumnPair.this.setTargetColumn(null);
+			}
+			@Override
+			public String toString() {
+				return "MWColumnPair.buildTargetColumnScrubber()";
+			}
+		};
+	}
+
+
+	// ********** importing/refreshing **********
+
+	/**
+	 * Returns whether the column pair corresponds to the specified
+	 * "external" column pair;
+	 * if the column pair matches an "external" column pair we keep,
+	 * otherwise, we remove it from the reference
+	 */
+	boolean matches(ExternalForeignKeyColumnPair externalPair) {
+		return (this.getSourceColumn() == this.sourceColumn(externalPair)) &&
+				(this.getTargetColumn() == this.targetColumn(externalPair));
+	}
+
+	/**
+	 * Returns the column in the source table with the same name as the
+	 * "external" column pair's source column
+	 */
+	private ELColumn sourceColumn(ExternalForeignKeyColumnPair externalPair) {
+		return this.getReference().sourceColumn(externalPair);
+	}
+
+	/**
+	 * Returns the column in the target table with the same name as the
+	 * "external" column pair's target column
+	 */
+	private ELColumn targetColumn(ExternalForeignKeyColumnPair externalPair) {
+		return this.getReference().targetColumn(externalPair);
+	}
+
+	// ********** displaying and printing **********
+
+	@Override
+	public String displayString() {
+		return this.getName();
+	}
+
+	public void toString(StringBuffer sb) {
+		this.printColumnNameOn(this.getSourceColumn(), sb);
+		sb.append("=>");
+		this.printColumnNameOn(this.getTargetColumn(), sb);
+	}
+
+	private void printColumnNameOn(ELColumn column, StringBuffer sb) {
+		sb.append((column == null) ? "null" : column.getName());
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java
new file mode 100644
index 0000000..d899424
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELDatabase.java
@@ -0,0 +1,914 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import org.eclipse.persistence.sessions.Connector;
+import org.eclipse.persistence.sessions.DatabaseSession;
+import org.eclipse.persistence.sessions.Project;
+import org.eclipse.persistence.sessions.Session;
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle.NodeReferenceScrubber;
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabaseFactory;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
+import org.eclipse.persistence.tools.db.relational.spi.jdbc.JDBCExternalDatabaseFactory;
+import org.eclipse.persistence.tools.schemaframework.SchemaManager;
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELDatabase extends ELModel {
+
+	/** the database platform should never be null */
+	private volatile DatabasePlatform databasePlatform;
+		public static final String DATABASE_PLATFORM_PROPERTY = "databasePlatform" ;
+
+	private Collection<ELLoginSpec> loginSpecs;
+		public static final String LOGIN_SPECS_COLLECTION = "loginSpecs";
+
+	private ELLoginSpecHandle deploymentLoginSpecHandle;
+		public static final String DEPLOYMENT_LOGIN_SPEC_PROPERTY = "deploymentLoginSpec";
+	private ELLoginSpecHandle developmentLoginSpecHandle;
+		public static final String DEVELOPMENT_LOGIN_SPEC_PROPERTY = "developmentLoginSpec";
+
+	private Collection<ELTable> tables;
+		public static final String TABLES_COLLECTION = "tables";
+
+	/**
+	 * the "external" database that supplies the
+	 * "external" tables used to build MWTables
+	 */
+	private volatile ExternalDatabase externalDatabase;
+
+	/**
+	 * transient - java.sql.Driver used to connect to the database;
+	 * this field is always null when executing under jdev
+	 */
+	private volatile Driver driver;
+
+	/**
+	 * transient - java.sql.Connection used for collecting meta-data;
+	 * this field is always null when executing under jdev
+	 */
+	private volatile Connection connection;
+		// virtual property
+		public static final String CONNECTED_PROPERTY = "connected";
+
+	/**
+	 * transient - org.eclipse.persistence.tools.schemaframework.SchemaManager
+	 * used for generating tables on the database;
+	 * this field is always null when executing under jdev
+	 */
+	private volatile SchemaManager schemaManager;
+
+	private volatile ExternalDatabaseFactory dbFactory;
+
+	/**
+	 * these table names are read in by TopLink and are then
+	 * used and managed by the IOManager;
+	 * DO NOT use them for anything else  ~bjv
+	 */
+	private Collection<String> tableNames;
+		private static final String TABLE_NAMES_COLLECTION = "tableNames";
+
+	/** this setting queried reflectively by the I/O Manager; so don't remove it */
+	private static final String SUB_DIRECTORY_NAME = "tables";
+
+	// ********** constructors **********
+
+	public ELDatabase(DatabasePlatform databasePlatform) {
+		super(null);
+		this.databasePlatform = databasePlatform;
+	}
+
+
+	// ********** initialization **********
+
+	@Override
+	protected void checkParent(Node parentNode) {
+		// no-op since db is the root node
+	}
+
+	/**
+	 * initialize transient state
+	 */
+	@Override
+	public void initialize() {
+		super.initialize();
+		// the tables are not mapped directly
+		this.tables = new Vector<ELTable>();
+	}
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		this.loginSpecs = new Vector<ELLoginSpec>();
+		// 'deploymentLoginSpec' and 'developmentLoginSpec'
+		// are handled directly in #loginSpecRemoved(MWLoginSpec)
+		this.deploymentLoginSpecHandle = new ELLoginSpecHandle(this, NodeReferenceScrubber.NULL_INSTANCE);
+		this.developmentLoginSpecHandle = new ELLoginSpecHandle(this, NodeReferenceScrubber.NULL_INSTANCE);
+		this.tableNames = new HashSet<String>();
+	}
+
+	@Override
+	public Validator getValidator() {
+		return new Validator() {
+
+			@Override
+			public void validate() {
+			}
+
+			@Override
+			public void resume() {
+			}
+
+			@Override
+			public void pause() {
+			}
+		};
+	}
+
+
+	// ********** database platform **********
+
+	public DatabasePlatform getDatabasePlatform() {
+		return this.databasePlatform;
+	}
+
+	public void setDatabasePlatform(DatabasePlatform databasePlatform) {
+		if (databasePlatform == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.databasePlatform;
+		this.databasePlatform = databasePlatform;
+		this.firePropertyChanged(DATABASE_PLATFORM_PROPERTY, old, databasePlatform);
+		if (this.attributeValueHasChanged(old, databasePlatform)) {
+			this.databasePlatformChanged();
+		}
+	}
+
+	/**
+	 * cascade to the database fields so they can update their types
+	 */
+	private void databasePlatformChanged() {
+		synchronized (this.tables) {
+			for (ELTable table : this.tables) {
+				table.databasePlatformChanged();
+			}
+		}
+	}
+
+
+	// ********** login specs **********
+
+	public Iterator<ELLoginSpec> loginSpecs() {
+		return new CloneIterator<ELLoginSpec>(this.loginSpecs) {
+			@Override
+			protected void remove(ELLoginSpec current) {
+				ELDatabase.this.removeLoginSpec(current);
+			}
+		};
+	}
+
+	public int loginSpecsSize() {
+		return this.loginSpecs.size();
+	}
+
+	public ELLoginSpec addLoginSpec(String loginSpecName) {
+		this.checkLoginSpecName(loginSpecName);
+		return this.addLoginSpec(new ELLoginSpec(this, loginSpecName));
+	}
+
+	private ELLoginSpec addLoginSpec(ELLoginSpec loginSpec) {
+		this.addItemToCollection(loginSpec, this.loginSpecs, LOGIN_SPECS_COLLECTION);
+		if (this.loginSpecs.size() == 1) {
+			this.setDeploymentLoginSpec(loginSpec);
+			this.setDevelopmentLoginSpec(loginSpec);
+		}
+		return loginSpec;
+	}
+
+	public void removeLoginSpec(ELLoginSpec loginSpec) {
+		if (this.removeItemFromCollection(loginSpec, this.loginSpecs, LOGIN_SPECS_COLLECTION)) {
+			this.loginSpecRemoved(loginSpec);
+		}
+	}
+
+	public boolean containsLoginSpecNamed(String loginSpecName) {
+		return this.loginSpecNamed(loginSpecName) != null;
+	}
+
+	public ELLoginSpec loginSpecNamed(String loginSpecName) {
+		synchronized (this.loginSpecs) {
+			for (ELLoginSpec spec : this.loginSpecs) {
+				if (spec.getName().equals(loginSpecName)) {
+					return spec;
+				}
+			}
+		}
+		return null;
+	}
+
+	public Iterator<String> loginSpecNames() {
+		return new TransformationIterator<String, ELLoginSpec>(this.loginSpecs()) {
+			@Override
+			protected String transform(ELLoginSpec next) {
+				return next.getName();
+			}
+		};
+	}
+
+
+	// ********** deployment login spec **********
+
+	public ELLoginSpec getDeploymentLoginSpec() {
+		return this.deploymentLoginSpecHandle.getLoginSpec();
+	}
+
+	public void setDeploymentLoginSpec(ELLoginSpec loginSpec) {
+		Object old = this.deploymentLoginSpecHandle.getLoginSpec();
+		this.deploymentLoginSpecHandle.setLoginSpec(loginSpec);
+		this.firePropertyChanged(DEPLOYMENT_LOGIN_SPEC_PROPERTY, old, loginSpec);
+	}
+
+
+	// ********** development login spec **********
+
+	public ELLoginSpec getDevelopmentLoginSpec() {
+		return this.developmentLoginSpecHandle.getLoginSpec();
+	}
+
+	public void setDevelopmentLoginSpec(ELLoginSpec loginSpec) {
+		Object old = this.developmentLoginSpecHandle.getLoginSpec();
+		this.developmentLoginSpecHandle.setLoginSpec(loginSpec);
+		this.firePropertyChanged(DEVELOPMENT_LOGIN_SPEC_PROPERTY, old, loginSpec);
+	}
+
+
+	// ********** tables **********
+
+	public Iterator<ELTable> tables() {
+		return new CloneIterator<ELTable>(this.tables) {
+			@Override
+			protected void remove(ELTable current) {
+				ELDatabase.this.removeTable(current);
+			}
+		};
+	}
+
+	public int tablesSize() {
+		return this.tables.size();
+	}
+
+	public ELTable addTable(String shortName) {
+		return this.addTable(null, shortName);
+	}
+
+	public ELTable addTable(String schema, String shortName) {
+		return this.addTable(null, schema, shortName);
+	}
+
+	public ELTable addTable(String catalog, String schema, String shortName) {
+		this.checkTableName(catalog, schema, shortName, null);
+		return this.addTable(new ELTable(this, catalog, schema, shortName));
+	}
+
+	public ELTable addTableWithFullyQualifiedName(String fullyQualifiedName) {
+		Collection<String> strings = CollectionTools.collection(fullyQualifiedName.split("\\."));
+   		CollectionTools.removeAllOccurrences(strings, StringTools.EMPTY_STRING);
+   		String[] parsedName = strings.toArray(new String[strings.size()]);
+   		if (parsedName.length == 3) {
+   			return addTable(parsedName[0], parsedName[1], parsedName[2]);
+   		}
+   		else if (parsedName.length == 2) {
+   			return addTable(parsedName[0], parsedName[1]);
+   		}
+   		else {
+  			return addTable(parsedName[0]);
+  		}
+   	}
+
+	private ELTable addTable(ELTable table) {
+		this.addItemToCollection(table, this.tables, TABLES_COLLECTION);
+		return table;
+	}
+
+	public void removeTable(ELTable table) {
+		this.removeNodeFromCollection(table, this.tables, TABLES_COLLECTION);
+	}
+
+	public boolean containsTableNamed(String catalog, String schema, String shortName) {
+		return this.tableNamed(catalog, schema, shortName) != null;
+	}
+
+	public ELTable tableNamed(String catalog, String schema, String shortName) {
+		synchronized (this.tables) {
+			for (ELTable table : this.tables) {
+				if (table.nameMatches(catalog, schema, shortName)) {
+					return table;
+				}
+			}
+		}
+		return null;
+	}
+
+	public boolean containsTableNamedIgnoreCase(String catalog, String schema, String shortName) {
+		return this.tableNamedIgnoreCase(catalog, schema, shortName) != null;
+	}
+
+	public ELTable tableNamedIgnoreCase(String catalog, String schema, String shortName) {
+		synchronized (this.tables) {
+			for (ELTable table : this.tables) {
+				if (table.nameMatchesIgnoreCase(catalog, schema, shortName)) {
+					return table;
+				}
+			}
+		}
+		return null;
+	}
+
+	public boolean containsTableNamed(String qualifiedName) {
+		return this.tableNamed(qualifiedName) != null;
+	}
+
+	public ELTable tableNamed(String qualifiedName) {
+		synchronized (this.tables) {
+			for (ELTable table : this.tables) {
+				if (table.qualifiedName().equals(qualifiedName)) {
+					return table;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * used to prevent adding a duplicate table
+	 */
+	public Iterator<String> tableNames() {
+		return new TransformationIterator<String, ELTable>(this.tables()) {
+			@Override
+			protected String transform(ELTable next) {
+				return next.getName();
+			}
+		};
+	}
+
+	public ELColumn columnNamed(String qualifiedName) {
+		ELTable table = this.tableNamed(ELColumn.parseTableNameFromQualifiedName(qualifiedName));
+		if (table == null) {
+			return null;
+		}
+		return table.columnNamed(ELColumn.parseColumnNameFromQualifiedName(qualifiedName));
+	}
+
+
+	// ********** external database **********
+
+	/**
+	 * PRIVATE - no one should need direct access to the external database
+	 */
+	public ExternalDatabase getExternalDatabase() {
+		if (this.externalDatabase == null) {
+			this.externalDatabase = this.buildExternalDatabase();
+		}
+		return this.externalDatabase;
+	}
+
+	private ExternalDatabase buildExternalDatabase() {
+		// when executing under jdev, the connection will be null
+		return this.externalDatabaseFactory().buildDatabase(this.connection);
+	}
+
+	private ExternalDatabaseFactory getExternalDatabaseFactory() {
+		if (this.dbFactory == null) {
+			this.dbFactory = new JDBCExternalDatabaseFactory();
+		}
+
+		return this.dbFactory;
+	}
+
+
+	// ********** connection **********
+
+	/**
+	 * this method is not called when executing under jdev
+	 */
+	public boolean isConnected() {
+		return this.connection != null;
+	}
+
+
+	// ********** schema manager **********
+
+	/**
+	 * call #isConnected()/#login() before calling this method or you
+	 * might get an IllegalStateException;
+	 * this method is not called when executing under jdev
+	 */
+	private SchemaManager getSchemaManager() {
+		if (this.schemaManager == null) {
+			throw new IllegalStateException("not connected");
+		}
+		return this.schemaManager;
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * the external database factory is supplied by client code
+	 */
+	private ExternalDatabaseFactory externalDatabaseFactory() {
+		return getExternalDatabaseFactory();
+	}
+
+	boolean supportsIdentityClause() {
+		return this.databasePlatform.supportsIdentityClause();
+	}
+
+
+	// ********** miscellaneous behavior **********
+
+	/**
+	 * 'connected' is a virtual property
+	 */
+	@Override
+	protected void addTransientAspectNamesTo(Set<String> transientAspectNames) {
+		super.addTransientAspectNamesTo(transientAspectNames);
+		transientAspectNames.add(CONNECTED_PROPERTY);
+	}
+
+	/**
+	 * disallow duplicate login info names
+	 */
+	void checkLoginSpecName(String loginSpecName) {
+		if ((loginSpecName == null) || (loginSpecName.length() == 0)) {
+			throw new IllegalArgumentException();
+		}
+		if (this.containsLoginSpecNamed(loginSpecName)) {
+			throw new IllegalArgumentException("duplicate login spec name: " + loginSpecName);
+		}
+	}
+
+	/**
+	 * disallow duplicate table names
+	 */
+	void checkTableName(String catalog, String schema, String shortName, ELTable table) {
+		this.checkTableNameQualifier(catalog);
+		this.checkTableNameQualifier(schema);
+		if ((shortName == null) || (shortName.length() == 0)) {
+			throw new IllegalArgumentException();
+		}
+		ELTable match = this.tableNamed(catalog, schema, shortName);
+		if (match != null) {
+			throw new IllegalArgumentException("duplicate table name: " + match.qualifiedName());
+		}
+		ELTable matchIgnoreCase = this.tableNamedIgnoreCase(catalog, schema, shortName);
+		if ((matchIgnoreCase != null) && (matchIgnoreCase != table)) {
+			throw new IllegalArgumentException("duplicate table name: " + matchIgnoreCase.qualifiedName());
+		}
+	}
+
+	/**
+	 * table qualifiers must be null or non-empty
+	 */
+	private void checkTableNameQualifier(String qualifier) {
+		if (qualifier == null) {
+			return;
+		}
+		if (qualifier.length() == 0) {
+			throw new IllegalArgumentException();
+		}
+	}
+
+
+	// ********** model synchronization **********
+
+	@Override
+	protected void addChildrenTo(List<Node> children) {
+		super.addChildrenTo(children);
+		synchronized (this.loginSpecs) { children.addAll(this.loginSpecs); }
+		children.add(this.deploymentLoginSpecHandle);
+		children.add(this.developmentLoginSpecHandle);
+		synchronized (this.tables) { children.addAll(this.tables); }
+	}
+
+	private void loginSpecRemoved(ELLoginSpec loginSpec) {
+		if (this.getDeploymentLoginSpec() == loginSpec) {
+			this.setDeploymentLoginSpec(null);
+		}
+		if (this.getDevelopmentLoginSpec() == loginSpec) {
+			this.setDevelopmentLoginSpec(null);
+		}
+	}
+
+	/**
+	 * performance tuning: override this method and assume
+	 * the database's descendants have NO references (handles)
+	 * to any models other than other descendants of the database
+	 */
+	@Override
+	public void nodeRemoved(Node node) {
+		if (node.isDescendantOf(this)) {
+			super.nodeRemoved(node);
+		}
+	}
+
+	/**
+	 * performance tuning: override this method and assume
+	 * the database's descendants have NO references (handles)
+	 * to any models other than other descendants of the database
+	 */
+	@Override
+	public void nodeRenamed(Node node) {
+		if (node.isDescendantOf(this)) {
+			super.nodeRenamed(node);
+			// we handle a renamed table directly in #tableRenamed()
+		}
+	}
+
+	// ********** login/logout **********
+
+	/**
+	 * you must log in before accessing the connection or
+	 * schema manager;
+	 * we instantiate and connect the JDBC Driver manually, ignoring
+	 * the stupid JDBC DriverManager;
+	 * this method is not called when executing under jdev
+	 */
+	public void login() throws SQLException, ClassNotFoundException {
+		if (this.isConnected()) {
+			throw new IllegalStateException("already connected");
+		}
+		ELLoginSpec loginSpec = this.getDevelopmentLoginSpec();
+		if (loginSpec == null) {
+			throw new IllegalStateException("missing development login spec");
+		}
+
+		try {
+			this.driver = loginSpec.buildDriver();
+		} catch (InstantiationException ex) {
+			throw new RuntimeException(ex);
+		} catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex);
+		}
+
+		String url = loginSpec.getURL();
+		if ((url == null) || (url.length() == 0)) {
+			throw new IllegalStateException("missing database URL");
+		}
+
+		// store the user name and password in a dictionary
+		Properties props = new Properties();
+		String userName = loginSpec.getUserName();
+		if (userName != null) {
+			props.put("user", userName);
+		}
+		String password = loginSpec.getPassword();
+		if (password != null) {
+			props.put("password", password);
+		}
+
+		this.connection = this.driver.connect(url, props);
+
+		// once we are connected we can build the schema manager
+		this.schemaManager = this.buildSchemaManager();
+		this.firePropertyChanged(CONNECTED_PROPERTY, false, true);
+	}
+
+	/**
+	 * disconnect from the database and clear out any state that relies
+	 * on the connection;
+	 * this method is not called when executing under jdev
+	 */
+	public void logout() throws SQLException {
+		if ( ! this.isConnected()) {
+			throw new IllegalStateException("not connected");
+		}
+		this.connection.close();
+		this.schemaManager = null;
+		this.connection = null;
+		this.driver = null;
+		this.externalDatabase = null;
+		this.firePropertyChanged(CONNECTED_PROPERTY, true, false);
+	}
+
+	private SchemaManager buildSchemaManager() {
+		return new SchemaManager(this.buildRuntimeDatabaseSession());
+	}
+
+	/**
+	 * this db session will use the *development* login spec;
+	 * this method is not called when executing under jdev
+	 */
+	private DatabaseSession buildRuntimeDatabaseSession() {
+		DatabaseSession session = this.buildRuntimeProject().createDatabaseSession();
+		session.dontLogMessages();
+		session.login();
+		return session;
+	}
+
+	/**
+	 * this project will use the *development* login spec
+	 * this method is not called when executing under jdev
+	 */
+	private Project buildRuntimeProject() {
+		return new Project(this.getDevelopmentLoginSpec().buildDevelopmentRuntimeDatabaseLogin());
+	}
+
+	/**
+	 * build a connector that will use the database's connection;
+	 * this method is not called when executing under jdev
+	 */
+	Connector buildRuntimeConnector() {
+		return new LocalConnectorAdapter(this.connection);
+	}
+
+
+	// ********** table importing/refreshing **********
+
+	/**
+	 * Returns the "catalog" names from the current database.
+	 * @see java.sql.DatabaseMetaData#getCatalogs()
+	 */
+	public Iterator<String> catalogNames() {
+		return new ArrayIterator<String>(this.getExternalDatabase().getCatalogNames());
+	}
+
+	/**
+	 * Returns the "schema" names from the current database.
+	 * @see java.sql.DatabaseMetaData#getSchemas()
+	 */
+	public Iterator<String> schemaNames() {
+		if (!getDatabasePlatform().getName().equals("MySQL")) {
+			return new ArrayIterator<String>(this.getExternalDatabase().getSchemaNames());
+		} else {
+			return new ArrayIterator<String>(this.getExternalDatabase().getCatalogNames());
+		}
+	}
+
+	/**
+	 * Returns the "table type" names from the current database.
+	 * @see java.sql.DatabaseMetaData#getTableTypes()
+	 */
+	public Iterator<String> tableTypeNames() {
+		return new ArrayIterator<String>(this.getExternalDatabase().getTableTypeNames());
+	}
+
+	/**
+	 * Returns the "external" table descriptions corresponding to the specified
+	 * search criteria; these can then be used to import and/or refresh tables
+	 * @see #externalTableDescriptions()
+	 * @see #importQualifiedTablesFor(java.util.Collection)
+	 * @see #importUnqualifiedTablesFor(java.util.Collection)
+	 * @see #refreshQualifiedTablesFor(java.util.Collection)
+	 * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
+	 */
+	public Iterator<ExternalTableDescription> externalTableDescriptions(String catalog, String schemaPattern, String tableNamePattern, String[] types) {
+		return new ArrayIterator<ExternalTableDescription>(
+			this.getExternalDatabase().getTableDescriptions(catalog, schemaPattern, tableNamePattern, types)
+		);
+	}
+
+	/**
+	 * Returns the all the "external" table descriptions;
+	 * these can then be used to import and/or refresh tables
+	 * @see #externalTableDescriptions(String, String, String, String[])
+	 * @see #importQualifiedTablesFor(java.util.Collection)
+	 * @see #importUnqualifiedTablesFor(java.util.Collection)
+	 * @see #refreshQualifiedTablesFor(java.util.Collection)
+	 */
+	public Iterator<ExternalTableDescription> externalTableDescriptions() {
+		return new ArrayIterator<ExternalTableDescription>(
+			this.getExternalDatabase().getTableDescriptions()
+		);
+	}
+
+	/**
+	 * import the tables corresponding to the specified
+	 * "external" table descriptions, using their fully-qualified names;
+	 * this is a two-step process: all the fields must be in place before
+	 * we can build or refresh the references
+	 */
+	public void importQualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			this.qualifiedTableFor(externalTableDescription).refreshColumns(externalTableDescription.getTable());
+		}
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			this.qualifiedTableFor(externalTableDescription).refreshReferences(externalTableDescription.getTable());
+		}
+	}
+
+	/**
+	 * refresh the tables corresponding to the specified "external" table descriptions, using their fully
+	 * qualified names; this is a two-step process: all the fields must be in place before
+	 * we can refresh the references;
+	 * we want different behavior here because we don't want to
+	 * create them if they don't exist and we must handle unqualified tables
+	 */
+	public void refreshQualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			ELTable tableToRefresh = this.tableNamed(externalTableDescription.getQualifiedName());
+			if (tableToRefresh == null) {
+				// the table's name may be unqualified
+				tableToRefresh = this.tableNamed(externalTableDescription.getName());
+			}
+			if (tableToRefresh != null) {
+				tableToRefresh.refreshColumns(externalTableDescription.getTable());
+			}
+		}
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			ELTable tableToRefresh = this.tableNamed(externalTableDescription.getQualifiedName());
+			if (tableToRefresh == null) {
+				// the table's name may be unqualified
+				tableToRefresh = this.tableNamed(externalTableDescription.getName());
+			}
+			if (tableToRefresh != null) {
+				tableToRefresh.refreshReferences(externalTableDescription.getTable());
+			}
+		}
+	}
+
+	/**
+	 * Returns the table corresponding to the specified "external" table description,
+	 * creating it if necessary; use the table's fully-qualified name
+	 */
+	private ELTable qualifiedTableFor(ExternalTableDescription externalTableDescription) {
+		if (getDatabasePlatform().getName().equals("MySQL")) {
+			return this.tableNamedForImport(null, externalTableDescription.getCatalogName(), externalTableDescription.getName());
+		} else {
+			return this.tableNamedForImport(externalTableDescription.getCatalogName(), externalTableDescription.getSchemaName(), externalTableDescription.getName());
+		}
+	}
+
+	/**
+	 * Returns the requested table, creating it if necessary
+	 */
+	private ELTable tableNamedForImport(String catalog, String schema, String shortName) {
+		ELTable table = this.tableNamed(catalog, schema, shortName);
+		if (table == null) {
+			table = this.addTable(catalog, schema, shortName);
+		}
+		return table;
+	}
+
+	/**
+	 * import and/or refresh the tables corresponding to the specified
+	 * "external" table descriptions, using their "short" names;
+	 * this is a two-step process: all the fields must be in place before
+	 * we can build or refresh the references
+	 */
+	public void importUnqualifiedTablesFor(Collection<ExternalTableDescription> externalTableDescriptions) {
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			this.unqualifiedTableFor(externalTableDescription).refreshColumns(externalTableDescription.getTable());
+		}
+		for (Iterator<ExternalTableDescription> stream = externalTableDescriptions.iterator(); stream.hasNext(); ) {
+			ExternalTableDescription externalTableDescription = stream.next();
+			this.unqualifiedTableFor(externalTableDescription).refreshReferences(externalTableDescription.getTable());
+		}
+	}
+
+	/**
+	 * Returns the table corresponding to the specified "external" table description,
+	 * creating it if necessary; use the table's "short" name
+	 */
+	private ELTable unqualifiedTableFor(ExternalTableDescription externalTableDescription) {
+		return this.tableNamedForImport(null, null, externalTableDescription.getName());
+	}
+
+	// ********** printing and displaying **********
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.getDatabasePlatform().getName());
+		sb.append(" : ");
+		sb.append(this.tables.size());
+		sb.append(" tables");
+	}
+
+	@Override
+	public String displayString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("Database (");
+		sb.append(this.getDatabasePlatform().getName());
+		sb.append(")");
+		return sb.toString();
+	}
+
+
+	// ********** SubComponentContainer implementation **********
+
+	public Iterator projectSubFileComponents() {
+		return this.tables();
+	}
+
+	public void setProjectSubFileComponents(Collection subComponents) {
+		this.tables = subComponents;
+	}
+
+	public Iterator originalProjectSubFileComponentNames() {
+		return this.tableNames.iterator();
+	}
+
+	public void setOriginalProjectSubFileComponentNames(Collection originalSubComponentNames) {
+		this.tableNames = originalSubComponentNames;
+	}
+
+	public boolean hasChangedMainProjectSaveFile() {
+		if (this.isDirty()) {
+			// the database itself is dirty
+			return true;
+		}
+		for (Iterator stream = this.children(); stream.hasNext(); ) {
+			if (this.childHasChangedTheProjectSaveFile(stream.next())) {
+				return true;
+			}
+		}
+		// the tables might be dirty
+		return false;
+	}
+
+	/**
+	 * Returns whether the specified child of the database is dirty AND
+	 * is written to the .mwp file
+	 */
+	private boolean childHasChangedTheProjectSaveFile(Object child) {
+		if (this.tables.contains(child)) {
+			// tables are written to separate files
+			return false;
+		}
+		// the child is NOT a table,
+		// so all of its state is written to the .mwp file
+		return ((Node) child).isDirtyBranch();
+	}
+
+	// ********** inner classes **********
+
+	/**
+	 * Adapt the database to the TopLink run-time Connector interface.
+	 */
+	private static class LocalConnectorAdapter implements Connector {
+		private Connection connection;
+		LocalConnectorAdapter(Connection connection) {
+			super();
+			this.connection = connection;
+		}
+		/** this is the only method of note */
+		@Override
+		public Connection connect(Properties properties, Session session) {
+			return this.connection;
+		}
+		@Override
+		public Object clone() {
+			try {
+				return super.clone();
+			} catch (CloneNotSupportedException ex) {
+				throw new InternalError();
+			}
+		}
+		@Override
+		public String getConnectionDetails() {
+			return "MWDatabase.LocalConnectorAdapter";
+		}
+		@Override
+		public void toString(PrintWriter writer) {
+			writer.print(this.getConnectionDetails());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java
new file mode 100644
index 0000000..c633983
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpec.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+import java.util.Vector;
+import org.eclipse.persistence.exceptions.DatabaseException;
+import org.eclipse.persistence.internal.security.JCEEncryptor;
+import org.eclipse.persistence.sessions.Connector;
+import org.eclipse.persistence.sessions.DatabaseLogin;
+import org.eclipse.persistence.sessions.Session;
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
+import org.eclipse.persistence.tools.utility.iterators.CloneListIterator;
+import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELLoginSpec extends ELModel {
+
+	/** the name should never be null or empty */
+	private volatile String name;
+		public static final String NAME_PROPERTY = "name";
+
+	private volatile String driverClassName;
+		public static final String DRIVER_CLASS_NAME_PROPERTY = "driverClassName";
+		// virtual collection
+		public static final String CANDIDATE_URLS_COLLECTION = "candidateURLs";
+
+	private volatile String url;
+		public static final String URL_PROPERTY = "url";
+
+	private volatile String userName;
+		public static final String USER_NAME_PROPERTY = "userName";
+
+	private volatile String password;
+		public static final String PASSWORD_PROPERTY = "password";
+
+	private volatile boolean savePassword;
+		public static final String SAVE_PASSWORD_PROPERTY = "savePassword";
+
+	private List<String> driverClasspathEntries;
+		public static final String DRIVER_CLASSPATH_ENTRIES_LIST = "driverClasspathEntries";
+
+	/** the JDBC drivers we know about and their URLs */
+	private static Collection<DriverSpec> driverSpecs;
+
+	/** cache this - it's expensive to instantiate */
+	private static JCEEncryptor encryptor;
+
+	/** preferences */
+	public static final String DB_DRIVER_CLASS_PREFERENCE = "database driver class";
+
+	public static final String DB_CONNECTION_URL_PREFERENCE = "database connection url";
+
+	// ********** static methods **********
+
+	/**
+	 * Returns the driver class names we know about
+	 */
+	public static Iterator<String> commonDriverClassNames() {
+		return new TransformationIterator<String, DriverSpec>(driverSpecs()) {
+			@Override
+			protected String transform(DriverSpec next) {
+				return next.getDriverClassName();
+			}
+		};
+	}
+
+	public static int commonDriverClassNamesSize() {
+		return getDriverSpecs().size();
+	}
+
+	/**
+	 * Returns the URLs typically associated with the specified
+	 * driver class name
+	 */
+	private static Iterator<String> urlsForDriverClassNamed(String driverClassName) {
+		DriverSpec ds = driverSpecFor(driverClassName);
+		return (ds == null) ? EmptyIterator.<String>instance() : ds.urls();
+	}
+
+	private static int urlsForDriverClassNamedSize(String driverClassName) {
+		DriverSpec ds = driverSpecFor(driverClassName);
+		return (ds == null) ? 0 : ds.urlsSize();
+	}
+
+	private static boolean urlsForDriverClassNamedContains(String driverClassName, String url) {
+		DriverSpec ds = driverSpecFor(driverClassName);
+		return (ds == null) ? false : ds.containsURL(url);
+	}
+
+	/**
+	 * Returns the URL most commonly used with the specified
+	 * driver class name
+	 */
+	private static String defaultURLForDriverClassNamed(String driverClassName) {
+		DriverSpec ds = driverSpecFor(driverClassName);
+		return (ds == null) ? null : ds.defaultURL();
+	}
+
+	private static DriverSpec driverSpecFor(String driverClassName) {
+		for (Iterator<DriverSpec> stream = driverSpecs(); stream.hasNext(); ) {
+			DriverSpec ds = stream.next();
+			if (ds.getDriverClassName().equals(driverClassName)) {
+				return ds;
+			}
+		}
+		return null;
+	}
+
+	private static Iterator<DriverSpec> driverSpecs() {
+		return getDriverSpecs().iterator();
+	}
+
+	private synchronized static Collection<DriverSpec> getDriverSpecs() {
+		if (driverSpecs == null) {
+			driverSpecs = buildDriverSpecs();
+		}
+		return driverSpecs;
+	}
+
+	// TODO move to DatabasePlatform and store in its XML file?
+	private static Collection<DriverSpec> buildDriverSpecs() {
+		Collection<DriverSpec> specs = new ArrayList<DriverSpec>(30);
+		specs.add(new DriverSpec("com.neon.jdbc.Driver", "jdbc:neon:"));
+		specs.add(new DriverSpec("com.pointbase.jdbc.jdbcUniversalDriver", "jdbc:pointbase:"));
+		specs.add(new DriverSpec("com.sybase.jdbc3.jdbc.SybDriver", "jdbc:sybase:Tds:"));
+		specs.add(new DriverSpec("com.sybase.jdbc2.jdbc.SybDriver", "jdbc:sybase:Tds:"));
+		specs.add(new DriverSpec("com.sybase.jdbc.SybDriver", "jdbc:sybase:Tds:"));
+		specs.add(new DriverSpec("COM.ibm.db2.jdbc.app.DB2Driver", "jdbc:db2:"));
+		specs.add(new DriverSpec("COM.ibm.db2.jdbc.net.DB2Driver", "jdbc:db2:"));
+		specs.add(new DriverSpec("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://"));
+		specs.add(new DriverSpec("com.mysql.jdbc.Driver", "jdbc:mysql://"));
+		specs.add(new DriverSpec("borland.jdbc.Bridge.LocalDriver", "jdbc:BorlandBridge:"));
+		specs.add(new DriverSpec("borland.jdbc.Broker.RemoteDriver", "jdbc:BorlandBridge:"));
+		specs.add(new DriverSpec("intersolv.jdbc.sequelink.SequeLinkDriver", "jdbc:sequelink:"));
+		String[] oracleURLs =
+				new String[] {
+					"jdbc:oracle:thin:@<HOST>:<PORT>:<SID>",
+					"jdbc:oracle:oci:@<HOST>:<PORT>:<SID>",
+					"jdbc:oracle:oci7:@<HOST>:<PORT>:<SID>",
+					"jdbc:oracle:oci8:@<HOST>:<PORT>:<SID>"
+				};
+		specs.add(new DriverSpec("oracle.jdbc.OracleDriver", oracleURLs));
+		specs.add(new DriverSpec("oracle.jdbc.driver.OracleDriver", oracleURLs));
+		specs.add(new DriverSpec("com.oracle.ias.jdbc.db2.DB2Driver", "jdbc:oracle:db2://"));
+		specs.add(new DriverSpec("com.oracle.ias.jdbc.sqlserver.SQLServerDriver", "jdbc:oracle:sqlserver://"));
+		specs.add(new DriverSpec("com.oracle.ias.jdbc.sybase.SybaseDriver", "jdbc:oracle:sybase://"));
+		specs.add(new DriverSpec("org.hsqldb.jdbcDriver", "jdbc:hsqldb:"));
+		specs.add(new DriverSpec("sun.jdbc.odbc.JdbcOdbcDriver", "jdbc:odbc:"));
+		specs.add(new DriverSpec("weblogic.jdbc.oci.Driver", "jdbc:weblogic:oracle:"));
+		specs.add(new DriverSpec("weblogic.jdbc.dblib.Driver", new String[] { "jdbc:weblogic:mssqlserver:", "jdbc:weblogic:sybase" }));
+		specs.add(new DriverSpec("weblogic.jdbc.informix4.Driver", "jdbc:weblogic:informix4:"));
+		specs.add(new DriverSpec("weblogic.jdbc.jts.Driver", "jdbc:weblogic:jts:"));
+		specs.add(new DriverSpec("weblogic.jdbc.mssqlserver4.Driver", "jdbc:weblogic:mssqlserver4:"));
+		specs.add(new DriverSpec("weblogic.jdbc.pool.Driver", "jdbc:weblogic:pool:"));
+		specs.add(new DriverSpec("weblogic.jdbc.t3client.Driver", "jdbc:weblogic:t3Client:"));
+		specs.add(new DriverSpec("weblogic.jdbc.t3.Driver", "jdbc:weblogic:t3:"));
+		specs.add(new DriverSpec("com.timesten.jdbc.TimesTenDriver", "jdbc:timesten:direct:<SID>"));
+		return specs;
+	}
+
+	private static JCEEncryptor getEncryptor() {
+		if (encryptor == null) {
+			try {
+				encryptor = new JCEEncryptor();
+			} catch (Exception ex) {
+				throw new RuntimeException(ex);
+			}
+		}
+		return encryptor;
+	}
+
+
+	// ********** constructors **********
+
+	ELLoginSpec(ELDatabase database, String name) {
+		super(database);
+		this.name = name;
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		this.savePassword = false;
+		this.driverClasspathEntries = new Vector<String>();
+	}
+
+
+	// ********** accessors **********
+
+	@Override
+	public final ELDatabase getParent() {
+		return (ELDatabase)super.getParent();
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+	public String getDriverClassName() {
+		return this.driverClassName;
+	}
+
+	public void setDriverClassName(String driverClassName) {
+		String old = this.driverClassName;
+		this.driverClassName = driverClassName;
+		this.firePropertyChanged(DRIVER_CLASS_NAME_PROPERTY, old, driverClassName);
+		if (this.attributeValueHasChanged(old, driverClassName)) {
+			// only change the URL if it is easy to re-create
+			if ((this.url == null) || urlsForDriverClassNamedContains(old, this.url)) {
+				this.setURL(defaultURLForDriverClassNamed(driverClassName));
+			}
+		}
+	}
+
+	public String getURL() {
+		return this.url;
+	}
+
+	public void setURL(String url) {
+		Object old = this.url;
+		this.url = url;
+		this.firePropertyChanged(URL_PROPERTY, old, url);
+	}
+
+	public String getUserName() {
+		return this.userName;
+	}
+
+	public void setUserName(String userName) {
+		Object old = this.userName;
+		this.userName = userName;
+		this.firePropertyChanged(USER_NAME_PROPERTY, old, userName);
+	}
+
+	public String getPassword() {
+		return this.password;
+	}
+
+	public void setPassword(String password) {
+		Object old = this.password;
+		this.password = password;
+		this.firePropertyChanged(PASSWORD_PROPERTY, old, password);
+	}
+
+	public boolean isSavePassword() {
+		return this.savePassword;
+	}
+
+	public void setSavePassword(boolean savePassword) {
+		boolean old = this.savePassword;
+		this.savePassword = savePassword;
+		this.firePropertyChanged(SAVE_PASSWORD_PROPERTY, old, savePassword);
+	}
+
+
+	/* NOTE: Driver classpath entries are Strings */
+
+	public ListIterator<String> driverClasspathEntries() {
+		return new CloneListIterator<String>(this.driverClasspathEntries);
+	}
+
+	public int driverClasspathEntriesSize() {
+		return this.driverClasspathEntries.size();
+	}
+
+	public String getDriverClasspathEntry(int index) {
+		return this.driverClasspathEntries.get(index);
+	}
+
+	public void addDriverClasspathEntry(int index, String entry) {
+		this.addItemToList(index, entry, this.driverClasspathEntries, DRIVER_CLASSPATH_ENTRIES_LIST);
+	}
+
+	public void addDriverClasspathEntry(String entry) {
+		this.addDriverClasspathEntry(this.driverClasspathEntriesSize(), entry);
+	}
+
+	public void addDriverClasspathEntries(int index, List<String> entries) {
+		this.addItemsToList(index, entries, this.driverClasspathEntries, DRIVER_CLASSPATH_ENTRIES_LIST);
+	}
+
+	public void addDriverClasspathEntries(List<String> entries) {
+		this.addDriverClasspathEntries(this.driverClasspathEntriesSize(), entries);
+	}
+
+	public void addDriverClasspathEntries(ListIterator<String> entries) {
+		this.addDriverClasspathEntries(CollectionTools.list(entries));
+	}
+
+	public String removeDriverClasspathEntry(int index) {
+		return this.removeItemFromList(index, this.driverClasspathEntries, DRIVER_CLASSPATH_ENTRIES_LIST);
+	}
+
+	public List<String> removeDriverClasspathEntries(int index, int length) {
+		return this.removeItemsFromList(index, length, this.driverClasspathEntries, DRIVER_CLASSPATH_ENTRIES_LIST);
+	}
+
+	public String replaceDriverClasspathEntry(int index, String newEntry) {
+		return this.setItemInList(index, newEntry, this.driverClasspathEntries, DRIVER_CLASSPATH_ENTRIES_LIST);
+	}
+
+
+	// ********** queries **********
+
+	public String defaultURL() {
+		return defaultURLForDriverClassNamed(this.driverClassName);
+	}
+
+	public Iterator<String> candidateURLs() {
+		return urlsForDriverClassNamed(this.driverClassName);
+	}
+
+	public int candidateURLsSize() {
+		return urlsForDriverClassNamedSize(this.driverClassName);
+	}
+
+	// ********** behavior **********
+
+	Driver buildDriver() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+		if ((this.driverClassName == null) || (this.driverClassName.length() == 0)) {
+			throw new IllegalStateException("missing database driver class name");
+		}
+		// we should be able to load the driver with only a minimum classpath
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+		Class<?> driverClass = Class.forName(this.driverClassName, true, classLoader);
+		return (Driver) driverClass.newInstance();
+	}
+
+	/**
+	 * Returns a TopLink runtime connector for the spec's driver.
+	 */
+	public Connector buildConnector() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+		return new MWConnector(this.buildDriver(), this.getURL());
+	}
+
+
+	// ********** runtime conversion **********
+
+	private DatabasePlatform databasePlatform() {
+		return this.getParent().getDatabasePlatform();
+	}
+
+	/**
+	 * this is used to log in to the database in the UI
+	 */
+	DatabaseLogin buildDevelopmentRuntimeDatabaseLogin() {
+		DatabaseLogin login = this.buildRuntimeDatabaseLogin();
+		login.setConnector(this.getParent().buildRuntimeConnector());
+		return login;
+	}
+
+	/**
+	 * this is used to generate deployment XML
+	 */
+	DatabaseLogin buildDeploymentRuntimeDatabaseLogin() {
+		DatabaseLogin login = this.buildRuntimeDatabaseLogin();
+		if ( ! this.savePassword) {
+			login.setPassword(null);
+		}
+		return login;
+	}
+
+	private DatabaseLogin buildRuntimeDatabaseLogin() {
+		DatabaseLogin login = new DatabaseLogin();
+
+		login.setDriverClassName(this.driverClassName);
+		login.setDriverURLHeader(StringTools.EMPTY_STRING);
+		login.setDatabaseURL(this.url);
+		login.setUserName(this.userName);
+		login.setPassword(this.password);
+
+		login.setPlatformClassName(this.databasePlatform().getRuntimePlatformClassName());
+
+		return login;
+	}
+
+
+	// ********** displaying and printing **********
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.name);
+	}
+
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+
+	// ********** TopLink methods **********
+	@SuppressWarnings("unused")
+	private String getPasswordForTopLink() {
+		return (this.savePassword) ? this.encryptedPassword() : null;
+	}
+
+	private String encryptedPassword() {
+		return (this.password == null) ? null : getEncryptor().encryptPassword(password);
+	}
+
+	@SuppressWarnings("unused")
+	private void setPasswordForTopLink(String password) {
+		this.password = (password == null) ? null : getEncryptor().decryptPassword(password);
+	}
+
+	/**
+	 * passwords were not encrypted in 4.5 and earlier
+	 */
+	@SuppressWarnings("unused")
+	private void legacySetPasswordForTopLink(String password) {
+		this.password = password;
+	}
+
+	/**
+	 * Pair popular JDBC drivers with the typical URLs used
+	 * with them.
+	 */
+	// TODO need a better class name
+	private static final class DriverSpec {
+		private String driverClassName;
+		private String[] urls;
+
+		DriverSpec(String driverClassName, String[] urls) {
+			super();
+			if ((driverClassName == null) || (driverClassName.length() == 0)) {
+				throw new IllegalArgumentException();
+			}
+			this.driverClassName = driverClassName;
+			if ((urls == null) || (urls.length == 0)) {
+				throw new IllegalArgumentException();
+			}
+			this.urls = urls;
+		}
+
+		DriverSpec(String driverClassName, String url) {
+			this(driverClassName, new String[] {url});
+		}
+
+		public String getDriverClassName() {
+			return this.driverClassName;
+		}
+
+		public Iterator<String> urls() {
+			return new ArrayIterator<String>(this.urls);
+		}
+
+		public int urlsSize() {
+			return this.urls.length;
+		}
+
+		public boolean containsURL(String url) {
+			for (int i = this.urls.length; i-- > 0; ) {
+				if (this.urls[i].equals(url)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public String defaultURL() {
+			return this.urls[0];
+		}
+
+		@Override
+		public String toString() {
+			return StringTools.buildToStringFor(this, this.driverClassName);
+		}
+	}
+
+	/**
+	 * Implement a TopLink runtime Connector that ignores the JDBC
+	 * DriverManager and uses a specified JDBC Driver. This allows us
+	 * to load Drivers dynamically without worrying about which class
+	 * loader loaded the driver and whether it is the same class loader
+	 * that loaded the driver's client.
+	 *
+	 * @see java.sql.DriverManager
+	 */
+	private static class MWConnector implements Connector {
+		private Driver driver;
+		private String url;
+
+		public MWConnector(Driver driver, String url) {
+			super();
+			this.driver = driver;
+			this.url = url;
+		}
+
+		@Override
+		public Connection connect(Properties properties, Session session) {
+			try {
+				return this.driver.connect(this.url, properties);
+			} catch (SQLException ex) {
+				throw DatabaseException.sqlException(ex);
+			}
+		}
+
+		@Override
+		public Object clone() {
+			try {
+				return super.clone();
+			}
+			catch (Exception exception) {
+				throw new InternalError("clone failed");
+			}
+		}
+
+		@Override
+		public String getConnectionDetails() {
+			return "MWConnector: " + this.url;
+		}
+
+		@Override
+		public void toString(PrintWriter writer) {
+			writer.println(this.getConnectionDetails());
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpecHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpecHandle.java
new file mode 100644
index 0000000..649d4da
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELLoginSpecHandle.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * <code>ELLoginSpecHandle</code> is used to isolate the painful bits of code necessary to correctly
+ * handle references to {@link ELLoginSpec} objects. Since a {@link ELLoginSpec} is nested within
+ * the XML file for a MWDatabase, we need to store a reference to a particular login spec as
+ *   - the name of the login spec
+ * <p>
+ * This causes no end of pain when dealing with TopLink, property change listeners, backward-
+ * compatibility, etc.
+ * <p>
+ * NB: Currently this class is only used by MWDatabase. The model synchronization is performed
+ * locally by that class since it holds the child collection of login specs ('loginSpecs') as well
+ * as thereferences to them ('deploymentLoginSpec' and 'developmentLoginSpec'). If this handle is
+ * ever used in another place in the model, the model synchronization will need to cascade to all
+ * model objects
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELLoginSpecHandle extends MWHandle {
+
+	/**
+	 * This is the actual login spec.
+	 * It is built from the login spec name, below.
+	 */
+	private volatile ELLoginSpec loginSpec;
+
+	/**
+	 * The login spec name is transient. It is used only to hold its value
+	 * until #postProjectBuild() is called and we can resolve
+	 * the actual login spec. We do not keep it in synch with the login spec
+	 * itself because we cannot know when the login spec has been renamed etc.
+	 */
+	private volatile String loginSpecName;
+
+	// ********** constructors **********
+
+	/**
+	 * default constructor - for TopLink use only
+	 */
+	@SuppressWarnings("unused")
+	private ELLoginSpecHandle() {
+		super();
+	}
+
+	ELLoginSpecHandle(ELDatabase parent, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+	}
+
+	ELLoginSpecHandle(ELDatabase parent, ELLoginSpec loginSpec, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+		this.loginSpec = loginSpec;
+	}
+
+
+	// ********** instance methods **********
+
+	ELLoginSpec getLoginSpec() {
+		return this.loginSpec;
+	}
+
+	void setLoginSpec(ELLoginSpec loginSpec) {
+		this.loginSpec = loginSpec;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Node node() {
+		return getLoginSpec();
+	}
+
+	public ELLoginSpecHandle setScrubber(NodeReferenceScrubber scrubber) {
+		this.setScrubberInternal(scrubber);
+		return this;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.loginSpec == null) {
+			sb.append("null");
+		} else {
+			this.loginSpec.toString(sb);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java
new file mode 100644
index 0000000..d950547
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELModel.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * @version 2.5
+ */
+public abstract class ELModel extends AbstractNode
+                              implements ELNode {
+
+	// ********** constructors **********
+
+	/**
+	 * Every object (except MWProject) must have a parent.
+	 * Use this constructor to create a new object - the default
+	 * constructor should only be used by TopLink.
+	 * @see #initialize(Node)
+	 */
+	protected ELModel(ELNode parent) {
+		super(parent);
+	}
+
+
+	// ********** convenience methods **********
+
+	/**
+	 * Returns the object's parent in the containment hierarchy.
+	 * Every object except the MWProject will have a parent.
+	 */
+	// TODO this can be renamed to getParent() when we move to jdk 1.5
+	@Override
+	public final ELNode getMWParent() {
+		return (ELNode) getParent();
+	}
+
+	// ********** model synchronization support **********
+
+	/**
+	 * Convenience method.
+	 * Remove the specified node from the specified bound collection,
+	 * firing the appropriate change event if necessary and
+	 * launching the cascading #nodeRemoved() mechanism.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodeFromCollection(Node node, Collection collection, String collectionName) {
+		boolean changed = this.removeItemFromCollection(node, collection, collectionName);
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified node from the specified collection
+	 * and launch the cascading #nodeRemoved() mechanism.
+	 * No change event is fired.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodeFromCollection(Node node, Collection collection) {
+		boolean changed = collection.remove(node);
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified nodes from the specified bound collection,
+	 * firing the appropriate change event if necessary and
+	 * launching the cascading #nodeRemoved() mechanism.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodesFromCollection(Collection nodes, Collection collection, String collectionName) {
+		return this.removeNodesFromCollection(nodes.iterator(), collection, collectionName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified nodes from the specified bound collection,
+	 * firing the appropriate change event if necessary,
+	 * and launch the cascading #nodeRemoved() mechanism.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodesFromCollection(Iterator nodes, Collection collection, String collectionName) {
+		Collection removedNodes = CollectionTools.collection(nodes);
+		removedNodes.retainAll(collection);
+		boolean changed = this.removeItemsFromCollection(nodes, collection, collectionName);
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified nodes from the specified collection
+	 * and launch the cascading #nodeRemoved() mechanism.
+	 * No change event is fired.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodesFromCollection(Collection nodes, Collection collection) {
+		return this.removeNodesFromCollection(nodes.iterator(), collection);
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified nodes from the specified collection
+	 * and launch the cascading #nodeRemoved() mechanism.
+	 * No change event is fired.
+	 * Returns true if the collection changed - @see java.util.Collection.remove(Object).
+	 */
+	protected boolean removeNodesFromCollection(Iterator nodes, Collection collection) {
+		Collection removedNodes = CollectionTools.collection(nodes);
+		removedNodes.retainAll(collection);
+		boolean changed = collection.removeAll(removedNodes);
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the specified collection, firing the appropriate change event
+	 * if necessary and launching the cascading #nodeRemoved() mechanism.
+	 */
+	protected void clearNodeCollection(Collection nodeCollection, String collectionName) {
+		Collection removedNodes = new ArrayList(nodeCollection);
+		this.clearCollection(nodeCollection, collectionName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the specified collection and launch the cascading #nodeRemoved()
+	 * mechanism.
+	 * No change event is fired.
+	 */
+	protected void clearNodeCollection(Collection nodeCollection) {
+		Collection removedNodes = new ArrayList(nodeCollection);
+		nodeCollection.clear();
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the node specified by index from the specified bound list,
+	 * firing the appropriate change event if necessary and
+	 * launching the cascading #nodeRemoved() mechanism.
+	 * Returns the removed object - @see java.util.List.remove(int).
+	 */
+	protected Object removeNodeFromList(int index, List nodeList, String listName) {
+		Node removedNode = (Node) this.removeItemFromList(index, nodeList, listName);
+		return removedNode;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the node specified by index from the specified list
+	 * and launch the cascading #nodeRemoved() mechanism.
+	 * No change event is fired.
+	 * Returns the removed object - @see java.util.List.remove(int).
+	 */
+	protected Object removeNodeFromList(int index, List list) {
+		Node removedNode = (Node) list.remove(index);
+		return removedNode;
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the specified list, firing the appropriate change event if necessary
+	 * and launching the cascading #nodeRemoved() mechanism.
+	 */
+	protected void clearNodeList(List nodeList, String listName) {
+		Collection removedNodes = new ArrayList(nodeList);
+		this.clearList(nodeList, listName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the specified list and launch the cascading #nodeRemoved() mechanism.
+	 * No change event is fired.
+	 */
+	protected void clearNodeList(List nodeList) {
+		// since no events thrown, same as for collection
+		this.clearNodeCollection(nodeList);
+	}
+
+	// ********** display methods **********
+
+	/**
+	 * Returns something useful for the UI.
+	 */
+	@Override
+	public String displayString() {
+		// the default is to use the developer-friendly string...
+		return this.toString();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELNode.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELNode.java
new file mode 100644
index 0000000..ce3da52
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELNode.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ *
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @version 2.5
+ */
+public interface ELNode extends Node {
+
+	ELNode getMWParent();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java
new file mode 100644
index 0000000..5941071
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELReference.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle;
+import org.eclipse.persistence.tools.db.relational.handles.MWTableHandle;
+import org.eclipse.persistence.tools.db.relational.handles.MWHandle.NodeReferenceScrubber;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * A reference describes a foreign-key relationship from a "source" table (the reference's "parent")
+ * to a "target" table. The foreign-key constraint can either be real ("on database") or virtual
+ * (only implied by the joins performed by TopLink).
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELReference extends ELModel {
+
+	/** the name should never be null or empty */
+	private volatile String name;
+		public static final String NAME_PROPERTY = "name";
+
+	private MWTableHandle targetTableHandle;
+		public static final String TARGET_TABLE_PROPERTY = "targetTable";
+
+	private Collection<ELColumnPair> columnPairs;
+		public static final String COLUMN_PAIRS_COLLECTION = "columnPairs";
+
+	/**
+	 * indicate whether the reference is an actual database constraint or
+	 * only used by TopLink for joining
+	 */
+	private volatile boolean onDatabase;
+		public static final String ON_DATABASE_PROPERTY = "onDatabase";
+
+	// ********** constructors **********
+
+	ELReference(ELTable parent, String name, ELTable targetTable) {
+		super(parent);
+		this.name = name;
+		this.targetTableHandle.setTable(targetTable);
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		this.targetTableHandle = new MWTableHandle(this, this.buildTargetTableScrubber());
+		this.columnPairs = new Vector<ELColumnPair>();
+		this.onDatabase = false;
+	}
+
+
+	// ********** accessors **********
+
+	public ELTable getSourceTable() {
+		return (ELTable) this.getParent();
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.getSourceTable().checkReferenceName(name);
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+	public ELTable getTargetTable() {
+		return this.targetTableHandle.getTable();
+	}
+
+	/**
+	 * if the target table changes, we clear out all the
+	 * column pairs, because they are now invalid
+	 */
+	public void setTargetTable(ELTable targetTable) {
+		Object old = this.targetTableHandle.getTable();
+		this.targetTableHandle.setTable(targetTable);
+		this.firePropertyChanged(TARGET_TABLE_PROPERTY, old, targetTable);
+		if (this.attributeValueHasChanged(old, targetTable)) {
+			this.clearColumnPairs();
+		}
+	}
+
+	public boolean isOnDatabase() {
+		return this.onDatabase;
+	}
+
+	public void setOnDatabase(boolean onDatabase) {
+		boolean old = this.onDatabase;
+		this.onDatabase = onDatabase;
+		this.firePropertyChanged(ON_DATABASE_PROPERTY, old, onDatabase);
+	}
+
+	// ********** column pairs
+	public Iterator<ELColumnPair> columnPairs() {
+		return new CloneIterator<ELColumnPair>(this.columnPairs) {
+			@Override
+			protected void remove(ELColumnPair current) {
+				ELReference.this.removeColumnPair(current);
+			}
+		};
+	}
+
+	public int columnPairsSize() {
+		return this.columnPairs.size();
+	}
+
+	public ELColumnPair addColumnPair(ELColumn sourceColumn, ELColumn targetColumn) {
+		if (sourceColumn.getTable() != this.getSourceTable()) {
+			throw new IllegalArgumentException("invalid source column: " + sourceColumn);
+		}
+		if (targetColumn.getTable() != this.getTargetTable()) {
+			throw new IllegalArgumentException("invalid target column: " + targetColumn);
+		}
+		return this.addColumnPair(new ELColumnPair(this, sourceColumn, targetColumn));
+	}
+
+	private ELColumnPair addColumnPair(ELColumnPair columnPair) {
+		this.addItemToCollection(columnPair, this.columnPairs,  COLUMN_PAIRS_COLLECTION);
+		return columnPair;
+	}
+
+	public void removeColumnPair(ELColumnPair columnPair) {
+		this.removeItemFromCollection(columnPair, this.columnPairs, COLUMN_PAIRS_COLLECTION);
+	}
+
+	public void removeColumnPairs(Iterator pairs) {
+		while (pairs.hasNext()) {
+			this.removeColumnPair((ELColumnPair) pairs.next());
+		}
+	}
+
+	public void removeColumnPairs(Collection pairs) {
+		this.removeColumnPairs(pairs.iterator());
+	}
+
+	private void clearColumnPairs() {
+		for (Iterator stream = this.columnPairs(); stream.hasNext(); ) {
+			stream.next();
+			stream.remove();
+		}
+	}
+
+	/**
+	 * used by MWColumnPairHandle
+	 */
+	public ELColumnPair columnPairNamed(String columnPairName) {
+		synchronized (this.columnPairs) {
+			for (Iterator stream = this.columnPairs.iterator(); stream.hasNext(); ) {
+				ELColumnPair pair = (ELColumnPair) stream.next();
+				if (pair.getName().equals(columnPairName)) {
+					return pair;
+				}
+			}
+		}
+		return null;
+	}
+
+	public ELColumnPair columnPairFor(ELColumn sourceColumn, ELColumn targetColumn) {
+		synchronized (this.columnPairs) {
+			for (Iterator stream = this.columnPairs.iterator(); stream.hasNext(); ) {
+				ELColumnPair pair = (ELColumnPair) stream.next();
+				if (pair.pairs(sourceColumn, targetColumn)) {
+					return pair;
+				}
+			}
+		}
+		return null;
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * this test is not entirely accurate, but it's close enough...
+	 */
+	public boolean isForeignKeyReference() {
+		return ! this.isPrimaryKeyReference();
+	}
+
+	/**
+	 * Returns whether the reference is a JOIN between the
+	 * primary keys on the source table with the primary keys
+	 * on the target table
+	 */
+	public boolean isPrimaryKeyReference() {
+		Collection sourcePrimaryKeys = CollectionTools.collection(this.getSourceTable().primaryKeyColumns());
+		if (sourcePrimaryKeys.size() != this.columnPairs.size()) {
+			return false;
+		}
+
+		Collection targetPrimaryKeys = CollectionTools.collection(this.getTargetTable().primaryKeyColumns());
+		if (targetPrimaryKeys.size() != this.columnPairs.size()) {
+			return false;
+		}
+
+		synchronized (this.columnPairs) {
+			for (Iterator stream = this.columnPairs.iterator(); stream.hasNext(); ) {
+				ELColumnPair pair = (ELColumnPair) stream.next();
+				if ( ! sourcePrimaryKeys.remove(pair.getSourceColumn())) {
+					return false;
+				}
+				if ( ! targetPrimaryKeys.remove(pair.getTargetColumn())) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+
+
+	// ********** model synchronization support **********
+
+	@Override
+	protected void addChildrenTo(List children) {
+		super.addChildrenTo(children);
+		children.add(this.targetTableHandle);
+		synchronized (this.columnPairs) { children.addAll(this.columnPairs); }
+	}
+
+	private NodeReferenceScrubber buildTargetTableScrubber() {
+		return new NodeReferenceScrubber() {
+			@Override
+			public void nodeReferenceRemoved(Node node, MWHandle handle) {
+				ELReference.this.setTargetTable(null);
+			}
+			@Override
+			public String toString() {
+				return "MWReference.buildTargetTableScrubber()";
+			}
+		};
+	}
+
+
+	// ********** importing/refreshing **********
+
+	/**
+	 * the reference has the same name as the specified "external" foreign key,
+	 * synchronize the reference's column pairs with the "external" foreign key's column pairs
+	 */
+	void refreshColumnPairs(ExternalForeignKey externalForeignKey) {
+		// after we have looped through the "external" column pairs,
+		// 'removedColumnPairs' will be left with the column pairs that need to be removed
+		Collection removedColumnPairs;
+		synchronized (this.columnPairs) {
+			removedColumnPairs = new HashSet(this.columnPairs);
+		}
+		ExternalForeignKeyColumnPair[] externalPairs = externalForeignKey.getColumnPairs();
+		for (int i = externalPairs.length; i-- > 0; ) {
+			this.refreshColumnPair(externalPairs[i], removedColumnPairs);
+		}
+		this.removeColumnPairs(removedColumnPairs);
+	}
+
+	private void refreshColumnPair(ExternalForeignKeyColumnPair externalPair, Collection removedColumnPairs) {
+		for (Iterator stream = removedColumnPairs.iterator(); stream.hasNext(); ) {
+			if (((ELColumnPair) stream.next()).matches(externalPair)) {
+				stream.remove();
+				return;
+			}
+		}
+		this.addColumnPair(this.sourceColumn(externalPair), this.targetColumn(externalPair));
+	}
+
+	/**
+	 * Returns the column in the source table with the same name as the
+	 * "external" column pair's source column
+	 */
+	ELColumn sourceColumn(ExternalForeignKeyColumnPair externalPair) {
+		return this.getSourceTable().column(externalPair.getSourceColumn());
+	}
+
+	/**
+	 * Returns the column in the target table with the same name as the
+	 * "external" column pair's target column
+	 */
+	ELColumn targetColumn(ExternalForeignKeyColumnPair externalPair) {
+		return this.getTargetTable().column(externalPair.getTargetColumn());
+	}
+
+	/**
+	 * Returns whether the reference has the same column pairs as
+	 * the specified "external" foreign key;
+	 * we compare column pairs because some references have system-
+	 * generated names that can change over the life of the reference
+	 * and we don't want to remove a reference simply because its
+	 * name changes - this would force the user to rebuild any objects
+	 * that referenced the [mistakenly] removed reference, e.g. mappings
+	 */
+	boolean matchesColumnPairs(ExternalForeignKey externalForeignKey) {
+		ExternalForeignKeyColumnPair[] externalPairs = externalForeignKey.getColumnPairs();
+		int externalPairsLength = externalPairs.length;
+		if (this.columnPairs.size() != externalPairsLength) {
+			return false;
+		}
+		Collection columnPairsCopy;
+		synchronized (this.columnPairs) {
+			columnPairsCopy = new HashSet(this.columnPairs);
+		}
+		for (int i = externalPairsLength; i-- > 0; ) {
+			ExternalForeignKeyColumnPair externalPair = externalPairs[i];
+			boolean match = false;
+			for (Iterator stream = columnPairsCopy.iterator(); stream.hasNext(); ) {
+				if (((ELColumnPair) stream.next()).matches(externalPair)) {
+					stream.remove();
+					match = true;
+					break;
+				}
+			}
+			if ( ! match) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	// ********** displaying and printing **********
+
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.name);
+		sb.append(" : ");
+		this.printTableNameOn(this.getSourceTable(), sb);
+		sb.append("=>");
+		this.printTableNameOn(this.getTargetTable(), sb);
+	}
+
+	private void printTableNameOn(ELTable table, StringBuffer sb) {
+		sb.append((table == null) ? "null" : table.getName());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java
new file mode 100644
index 0000000..ef0479f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/ELTable.java
@@ -0,0 +1,702 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.db.relational.platformsmodel.DatabasePlatform;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTable;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
+import org.eclipse.persistence.tools.utility.NameTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterators.CompositeIterator;
+import org.eclipse.persistence.tools.utility.iterators.FilteringIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class ELTable extends ELModel {
+
+	/** the catalog should never be empty - it can be null, but not empty */
+	private volatile String catalog;
+		public static final String CATALOG_PROPERTY = "catalog";
+
+	/** the schema should never be empty - it can be null, but not empty */
+	private volatile String schema;
+		public static final String SCHEMA_PROPERTY = "schema";
+
+	/** the short name should never be null OR empty */
+	private volatile String shortName;
+		public static final String SHORT_NAME_PROPERTY = "shortName";
+
+		public static final String QUALIFIED_NAME_PROPERTY = "qualifiedName";
+
+	/** this will be null if it is not known */
+	private Date lastRefreshTimestamp;
+		public static final String LAST_REFRESH_TIMESTAMP_PROPERTY = "lastRefreshTimestamp";
+
+	private Collection<ELColumn> columns;
+		public static final String COLUMNS_COLLECTION = "columns";
+
+	private Collection<ELReference> references;
+		public static final String REFERENCES_COLLECTION = "references";
+
+	private boolean legacyIsFullyQualified;
+
+	// ********** constructors **********
+
+	ELTable(ELDatabase database, String catalog, String schema, String shortName) {
+		super(database);
+		this.catalog = catalog;
+		this.schema = schema;
+		this.shortName = shortName;
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * initialize persistent state
+	 */
+	@Override
+	protected void initialize(Node parent) {
+		super.initialize(parent);
+		this.lastRefreshTimestamp = null;	// if the table is built by hand, this is left null
+		this.columns = new Vector<ELColumn>();
+		this.references = new Vector<ELReference>();
+	}
+
+
+	// ********** name: catalog, schema, shortName **********
+
+	public String getCatalog() {
+		return this.catalog;
+	}
+
+	/**
+	 * private - @see #rename(String, String, String)
+	 */
+	private void setCatalog(String catalog) {
+		Object old = this.catalog;
+		this.catalog = catalog;
+		if (this.attributeValueHasChanged(old, catalog)) {
+			this.firePropertyChanged(CATALOG_PROPERTY, old, catalog);
+			this.qualifiedNameChanged();
+		}
+	}
+
+	public String getSchema() {
+		return this.schema;
+	}
+
+	/**
+	 * private - @see #rename(String, String, String)
+	 */
+	private void setSchema(String schema) {
+		Object old = this.schema;
+		this.schema = schema;
+		if (this.attributeValueHasChanged(old, schema)) {
+			this.firePropertyChanged(SCHEMA_PROPERTY, old, schema);
+			this.qualifiedNameChanged();
+		}
+	}
+
+	public String getShortName() {
+		return this.shortName;
+	}
+
+	/**
+	 * private - @see #rename(String, String, String)
+	 */
+	private void setShortName(String shortName) {
+		Object old = this.shortName;
+		this.shortName = shortName;
+		if (this.attributeValueHasChanged(old, shortName)) {
+			this.firePropertyChanged(SHORT_NAME_PROPERTY, old, shortName);
+			this.qualifiedNameChanged();
+		}
+	}
+
+	private void qualifiedNameChanged() {
+		this.firePropertyChanged(QUALIFIED_NAME_PROPERTY, this.qualifiedName());
+		this.getParent().nodeRenamed(this);
+		for (Iterator<ELColumn> stream = this.columns(); stream.hasNext(); ) {
+			stream.next().qualifiedNameChanged();
+		}
+	}
+
+
+	// ********** columns **********
+
+	/**
+	 * this will be null if it is not known
+	 */
+	public Date getLastRefreshTimestamp() {
+		return this.lastRefreshTimestamp;
+	}
+
+	/**
+	 * PRIVATE - this can only be set internally
+	 */
+	private void setLastRefreshTimestamp(Date lastRefreshTimestamp) {
+		Object old = this.lastRefreshTimestamp;
+		this.lastRefreshTimestamp = lastRefreshTimestamp;
+		this.firePropertyChanged(LAST_REFRESH_TIMESTAMP_PROPERTY, old, lastRefreshTimestamp);
+	}
+
+
+	// ********** columns **********
+
+	public Iterator<ELColumn> columns() {
+		return new CloneIterator<ELColumn>(this.columns) {
+			@Override
+			protected void remove(ELColumn current) {
+				ELTable.this.removeColumn(current);
+			}
+		};
+	}
+
+	public int columnsSize() {
+		return this.columns.size();
+	}
+
+	public ELColumn addColumn(String name) {
+		this.checkColumnName(name);
+		return this.addColumn(new ELColumn(this, name));
+	}
+
+	private ELColumn addColumn(ELColumn column) {
+		this.addItemToCollection(column, this.columns, COLUMNS_COLLECTION);
+		return column;
+	}
+
+	public void removeColumn(ELColumn column) {
+		this.removeNodeFromCollection(column, this.columns, COLUMNS_COLLECTION);
+	}
+
+	public void removeColumns(Iterator<ELColumn> cols) {
+		while (cols.hasNext()) {
+			this.removeColumn(cols.next());
+		}
+	}
+
+	public void removeColumns(Collection<ELColumn> cols) {
+		this.removeColumns(cols.iterator());
+	}
+
+	public boolean containsColumnNamed(String columnName) {
+		return this.columnNamed(columnName) != null;
+	}
+
+	/**
+	 * only used for unqualified column names
+	 * @see #columnWithQualifiedName(String qualifiedName)
+	 */
+	public ELColumn columnNamed(String unqualifiedColumnName) {
+		synchronized (this.columns) {
+			for (Iterator<ELColumn> stream = this.columns.iterator(); stream.hasNext(); ) {
+				ELColumn column = stream.next();
+				if (column.getName().equals(unqualifiedColumnName)) {
+					return column;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the column with the specified "qualified" name
+	 */
+	public ELColumn columnWithQualifiedName(String name) {
+		if ( ! ELColumn.parseTableNameFromQualifiedName(name).equals(this.getName())) {
+			throw new IllegalArgumentException();
+		}
+		return this.columnNamed(ELColumn.parseColumnNameFromQualifiedName(name));
+	}
+
+	public Iterator<String> columnNames() {
+		return new TransformationIterator<String, ELColumn>(this.columns()) {
+			@Override
+			protected String transform(ELColumn next) {
+				return next.getName();
+			}
+		};
+	}
+
+	public int primaryKeyColumnsSize() {
+		int size = 0;
+		synchronized (this.columns) {
+			for (ELColumn column : this.columns) {
+				if (column.isPrimaryKey()) {
+					size++;
+				}
+			}
+		}
+		return size;
+	}
+
+	public Iterator<ELColumn> primaryKeyColumns() {
+		return new FilteringIterator<ELColumn>(this.columns()) {
+			@Override
+			protected boolean accept(ELColumn o) {
+				return o.isPrimaryKey();
+			}
+		};
+	}
+
+	public Iterator<String> primaryKeyColumnNames() {
+		return new TransformationIterator<String, ELColumn>(this.primaryKeyColumns()) {
+			@Override
+			protected String transform(ELColumn next) {
+				return next.getName();
+			}
+		};
+	}
+
+	public Iterator<ELColumn> nonPrimaryKeyColumns() {
+		return new FilteringIterator<ELColumn>(this.columns()) {
+			@Override
+			protected boolean accept(ELColumn o) {
+				return ! o.isPrimaryKey();
+			}
+		};
+	}
+
+	/**
+	 * used by table generation
+	 */
+	public ELColumn addColumnLike(ELColumn original) {
+		ELColumn copy = this.addColumn(original.getName());
+		copy.copySettingsFrom(original);
+		return copy;
+	}
+
+
+	// ********** references **********
+
+	public Iterator<ELReference> references() {
+		return new CloneIterator<ELReference>(this.references) {
+			@Override
+			protected void remove(ELReference current) {
+				ELTable.this.removeReference(current);
+			}
+		};
+	}
+
+	public int referencesSize() {
+		return this.references.size();
+	}
+
+	public ELReference addReference(String name, ELTable targetTable) {
+		this.checkReferenceName(name);
+		return this.addReference(new ELReference(this, name, targetTable));
+	}
+
+	private ELReference addReference(ELReference reference) {
+		this.addItemToCollection(reference, this.references, REFERENCES_COLLECTION);
+		return reference;
+	}
+
+	public void removeReference(ELReference reference) {
+		this.removeNodeFromCollection(reference, this.references, REFERENCES_COLLECTION);
+	}
+
+	public void removeReferences(Iterator<ELReference> refs) {
+		while (refs.hasNext()) {
+			this.removeReference(refs.next());
+		}
+	}
+
+	public void removeReferences(Collection<ELReference> refs) {
+		this.removeReferences(refs.iterator());
+	}
+
+	/**
+	 * remove only the references among those specified
+	 * that are defined on the database; leave any "virtual"
+	 * user-defined references
+	 */
+	private void removeDatabaseReferences(Iterator<ELReference> refs) {
+		while (refs.hasNext()) {
+			ELReference ref = refs.next();
+			if (ref.isOnDatabase()) {
+				this.removeReference(ref);
+			}
+		}
+	}
+
+	/**
+	 * remove only the references among those specified
+	 * that are defined on the database; leave any "virtual"
+	 * user-defined references
+	 */
+	private void removeDatabaseReferences(Collection<ELReference> refs) {
+		this.removeDatabaseReferences(refs.iterator());
+	}
+
+	public boolean containsReferenceNamed(String referenceName) {
+		return this.referenceNamed(referenceName) != null;
+	}
+
+	public ELReference referenceNamed(String referenceName) {
+		synchronized (this.references) {
+			for (Iterator<ELReference> stream = this.references.iterator(); stream.hasNext(); ) {
+				ELReference reference = stream.next();
+				if (reference.getName().equals(referenceName)) {
+					return reference;
+				}
+			}
+			return null;
+		}
+	}
+
+	public Iterator<String> referenceNames(){
+		return new TransformationIterator<String, ELReference>(this.references()) {
+			@Override
+			protected String transform(ELReference next) {
+				return next.getName();
+			}
+		};
+	}
+
+	/**
+	 * Returns the references that are actually present
+	 * as constraints on the database
+	 */
+	public Iterator<ELReference> databaseReferences() {
+		return new FilteringIterator<ELReference>(this.references()) {
+			@Override
+			protected boolean accept(ELReference o) {
+				return o.isOnDatabase();
+			}
+		};
+	}
+
+	/**
+	 * Returns all the references between the table and the
+	 * specified table (either table can be the source and/or target)
+	 */
+	@SuppressWarnings("unchecked")
+	public Iterator<ELReference> referencesBetween(ELTable table) {
+		return new CompositeIterator<ELReference>(
+			this.referencesTo(table),
+			table.referencesTo(this)
+		);
+	}
+
+	/**
+	 * Returns all the references with the table as the source and the
+	 * specified table as the target
+	 */
+	public Iterator<ELReference> referencesTo(final ELTable targetTable) {
+		return new FilteringIterator<ELReference>(this.references()) {
+			@Override
+			protected boolean accept(ELReference o) {
+				return o.getTargetTable() == targetTable;
+			}
+		};
+	}
+
+
+	// ********** Nominative implementation **********
+
+	/**
+	 * Returns the appropriately-qualified name
+	 */
+	public String getName() {
+		return this.qualifiedName();
+	}
+
+	//  ********** queries **********
+
+	public DatabasePlatform databasePlatform() {
+		 return this.getParent().getDatabasePlatform();
+	}
+
+	boolean nameMatches(String cat, String sch, String sn) {
+		return this.valuesAreEqual(this.catalog, cat) &&
+			this.valuesAreEqual(this.schema, sch) &&
+			this.valuesAreEqual(this.shortName, sn);
+	}
+
+	boolean nameMatchesIgnoreCase(String cat, String sch, String sn) {
+		return StringTools.stringsAreEqualIgnoreCase(this.catalog, cat) &&
+			StringTools.stringsAreEqualIgnoreCase(this.schema, sch) &&
+			StringTools.stringsAreEqualIgnoreCase(this.shortName, sn);
+	}
+
+	/**
+	 * if either the 'catalog' or 'schema' are specified,
+	 * the table's name is "qualified"
+	 */
+	public boolean nameIsQualified() {
+		if (this.catalog != null) {
+			return true;
+		}
+		if (this.schema != null) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean nameIsUnqualified() {
+		return ! this.nameIsQualified();
+	}
+
+	public String qualifiedName() {
+		return NameTools.buildQualifiedDatabaseObjectName(this.catalog, this.schema, this.shortName);
+	}
+
+	public String unqualifiedName() {
+		return this.shortName;
+	}
+
+	/**
+	 * used for table generation:
+	 *     catalog.schema
+	 *     catalog.
+	 *     schema
+	 */
+	private String qualifier() {
+		if (this.nameIsUnqualified()) {
+			return StringTools.EMPTY_STRING;
+		}
+		StringBuffer sb = new StringBuffer(100);
+		if (this.catalog != null) {
+			sb.append(this.catalog);
+		}
+		if (this.schema != null) {
+			if (this.catalog != null) {
+			sb.append('.');
+		}
+			sb.append(this.schema);
+		}
+		return sb.toString();
+	}
+
+
+	// ********** miscellaneous behavior **********
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ELDatabase getParent() {
+		return (ELDatabase)super.getParent();
+	}
+
+	@Override
+	protected void addChildrenTo(List<Node> children) {
+		super.addChildrenTo(children);
+		synchronized (this.columns) { children.addAll(this.columns); }
+		synchronized (this.references) { children.addAll(this.references); }
+	}
+
+	public void rename(String newCatalog, String newSchema, String newShortName) {
+		if (this.nameMatches(newCatalog, newSchema, newShortName)) {
+			// if someone is tryng to rename a table to its existing name, ignore it
+			return;
+		}
+		this.getParent().checkTableName(newCatalog, newSchema, newShortName, this);
+		this.setCatalog(newCatalog);
+		this.setSchema(newSchema);
+		this.setShortName(newShortName);
+	}
+
+	/**
+	 * disallow duplicate column names
+	 */
+	void checkColumnName(String columnName) {
+		if ((columnName == null) || (columnName.length() == 0)) {
+			throw new IllegalArgumentException();
+		}
+		if (this.containsColumnNamed(columnName)) {
+			throw new IllegalArgumentException("duplicate column name: " + columnName);
+		}
+	}
+
+	/**
+	 * disallow duplicate reference names
+	 */
+	void checkReferenceName(String referenceName) {
+		if ((referenceName == null) || (referenceName.length() == 0)) {
+			throw new IllegalArgumentException();
+		}
+		if (this.containsReferenceNamed(referenceName)) {
+			throw new IllegalArgumentException("duplicate reference name: " + referenceName);
+		}
+	}
+
+	void databasePlatformChanged() {
+		synchronized (this.columns) {
+			for (Iterator<ELColumn> stream = this.columns.iterator(); stream.hasNext(); ) {
+				stream.next().databasePlatformChanged();
+			}
+		}
+	}
+
+
+	// ********** importing/refreshing **********
+
+	/**
+	 * Returns the "external" table descriptions that share the table's name;
+	 * Returns multiple entries only when the table's name
+	 * is unqualified
+	 */
+	public Iterator<ExternalTableDescription> matchingExternalTableDescriptions() {
+		return this.getParent().externalTableDescriptions(this.catalog, this.schema, this.shortName, null);
+	}
+
+	/**
+	 * refresh the table's columns (but not the table's references - that
+	 * must be performed separately);
+	 */
+	void refreshColumns(ExternalTable externalTable) {
+		// after we have looped through the external columns,
+		// 'removedColumns' will be left with the columns that need to be removed
+		Collection<ELColumn> removedColumns;
+		synchronized (this.columns) {
+			removedColumns = new HashSet<ELColumn>(this.columns);
+		}
+		ExternalColumn[] externalColumns = externalTable.getColumns();
+		for (int i = externalColumns.length; i-- > 0; ) {
+			this.refreshColumn(externalColumns[i], removedColumns);
+		}
+		this.removeColumns(removedColumns);
+		this.setLastRefreshTimestamp(new Date());
+	}
+
+	/**
+	 * refresh the column corresponding to the specified "external" column
+	 */
+	private void refreshColumn(ExternalColumn externalColumn, Collection<ELColumn> removedColumns) {
+		ELColumn existingColumn = this.columnNamed(externalColumn.getName());
+		if (existingColumn == null) {
+			// we have a new column
+			existingColumn = this.addColumn(externalColumn.getName());
+		} else {
+			// retain the existing column
+			removedColumns.remove(existingColumn);
+		}
+		existingColumn.refresh(externalColumn);
+	}
+
+	/**
+	 * refresh the table's references - this should be called after
+	 * the table's columns have been refreshed and any target tables
+	 * have had their columns refreshed - this will allow us to build
+	 * the references properly
+	 */
+	void refreshReferences(ExternalTable externalTable) {
+		// after we have looped through the foreign keys,
+		// 'removedReferences' will be left with the references that need to be removed
+		Collection<ELReference> removedReferences;
+		synchronized (this.references) {
+			removedReferences = new HashSet<ELReference>(this.references);
+		}
+		ExternalForeignKey[] externalForeignKeys = externalTable.getForeignKeys();
+		for (int i = externalForeignKeys.length; i-- > 0; ) {
+			this.refreshReference(externalForeignKeys[i], removedReferences);
+		}
+
+		// remove *only* the remaining references that were originally defined on the database;
+		// leave the "virtual" user-defined references intact
+		this.removeDatabaseReferences(removedReferences);
+	}
+
+	/**
+	 * refresh the reference corresponding to the specified "external" foreign key;
+	 * search the 'removedReferences' so that we don't ever
+	 * refresh the same reference twice; first search for a match based
+	 * on name, then search for a match based on the column pairs - this
+	 * should prevent us from getting a match based on columns that has
+	 * the same name as another reference with different columns that
+	 * is further down the list
+	 */
+	private void refreshReference(ExternalForeignKey externalForeignKey, Collection<ELReference> removedReferences) {
+		// first, find the target table
+		ExternalTableDescription ttd = externalForeignKey.getTargetTableDescription();
+		ELTable targetTable = this.getParent().tableNamed(ttd.getCatalogName(), ttd.getSchemaName(), ttd.getName());
+		if (targetTable == null) {
+			// the target table may have been imported without
+			// a fully-qualified name, so try that also
+			targetTable = this.getParent().tableNamed(null, null, ttd.getName());
+		}
+		// if we don't have the target table, we can't build a reference to it
+		if (targetTable == null) {
+			return;
+		}
+
+		// look for a match based on name
+		for (Iterator<ELReference> stream = removedReferences.iterator(); stream.hasNext(); ) {
+			ELReference ref = stream.next();
+			if (ref.getName().equals(externalForeignKey.getName())) {
+				ref.setTargetTable(targetTable);
+				ref.refreshColumnPairs(externalForeignKey);
+				ref.setOnDatabase(true);
+				removedReferences.remove(ref);
+				return;
+			}
+		}
+
+		// look for a match based on column pairs
+		for (Iterator<ELReference> stream = removedReferences.iterator(); stream.hasNext(); ) {
+			ELReference ref = stream.next();
+			if (ref.matchesColumnPairs(externalForeignKey)) {
+				ref.setName(externalForeignKey.getName());
+				ref.setTargetTable(targetTable);
+				ref.setOnDatabase(true);
+				removedReferences.remove(ref);
+				return;
+			}
+		}
+
+		// no match - we have a new reference
+		ELReference ref = this.addReference(externalForeignKey.getName(), targetTable);
+		ExternalForeignKeyColumnPair[] pairs = externalForeignKey.getColumnPairs();
+		for (int i = pairs.length; i-- > 0; ) {
+			ref.addColumnPair(this.column(pairs[i].getSourceColumn()), targetTable.column(pairs[i].getTargetColumn()));
+		}
+		ref.setOnDatabase(true);
+	}
+
+	/**
+	 * Returns the column with the same name as the specified "external" column
+	 */
+	ELColumn column(ExternalColumn externalColumn) {
+		return (externalColumn == null) ? null : this.columnNamed(externalColumn.getName());
+	}
+
+	// ********** printing and displaying **********
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.qualifiedName());
+	}
+
+	@Override
+	public String displayString() {
+		return this.qualifiedName();
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/NodeModel.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/NodeModel.java
new file mode 100644
index 0000000..9f12393
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/NodeModel.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational;
+
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * Some nodes are models....
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @version 2.5
+ */
+public interface NodeModel extends Node {
+	// no additional behavior
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnHandle.java
new file mode 100644
index 0000000..49729c7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnHandle.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.handles;
+
+import org.eclipse.persistence.tools.db.relational.ELColumn;
+import org.eclipse.persistence.tools.db.relational.ELModel;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * MWColumnHandle is used to isolate the painful bits of code
+ * necessary to correctly handle references to MWColumns.
+ * Since a MWColumn is nested within the XML file
+ * for a MWTable, we need to store a reference to a particular
+ * column as a pair of instance variables:
+ *   - the name of the containing table
+ *   - the name of the column
+ *
+ * This causes no end of pain when dealing with TopLink, property
+ * change listeners, backward-compatibility, etc.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class MWColumnHandle extends MWHandle {
+
+	/**
+	 * This is the actual column.
+	 * It is built from the table and column names, below.
+	 */
+	private volatile ELColumn column;
+
+	/**
+	 * The table and column names are transient. They
+	 * are used only to hold their values until postProjectBuild()
+	 * is called and we can resolve the actual column.
+	 * We do not keep these in synch with the column itself because
+	 * we cannot know when the column has been renamed etc.
+	 */
+	private volatile String columnTableName;
+	private volatile String columnName;
+
+	// ********** constructors **********
+
+	/**
+	 * default constructor - for TopLink use only
+	 */
+	@SuppressWarnings("unused")
+	private MWColumnHandle() {
+		super();
+	}
+
+	public MWColumnHandle(ELModel parent, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+	}
+
+	public MWColumnHandle(ELModel parent, ELColumn column, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+		this.column = column;
+	}
+
+
+	// ********** instance methods **********
+
+	public ELColumn getColumn() {
+		return this.column;
+	}
+
+	public void setColumn(ELColumn column) {
+		this.column = column;
+	}
+
+	@Override
+	protected Node node() {
+		return this.getColumn();
+	}
+
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.column == null) {
+			sb.append("null");
+		} else {
+			this.column.toString(sb);
+		}
+	}
+
+	public MWColumnHandle setScrubber(NodeReferenceScrubber scrubber) {
+		this.setScrubberInternal(scrubber);
+		return this;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnPairHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnPairHandle.java
new file mode 100644
index 0000000..11b05ca
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWColumnPairHandle.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.handles;
+
+import org.eclipse.persistence.tools.db.relational.ELColumnPair;
+import org.eclipse.persistence.tools.db.relational.ELModel;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * MWColumnPairHandle is used to isolate the painful bits of code
+ * necessary to correctly handle references to MWColumnPairs.
+ * Since a MWColumnPair is nested within the XML file
+ * for a MWTable, we need to store a reference to a particular
+ * column pair as a list of instance variables:
+ *   - the name of the containing table
+ *   - the name of the containing reference
+ *   - the name of the column pair
+ *
+ * This causes no end of pain when dealing with TopLink, property
+ * change listeners, backward-compatibility, etc.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class MWColumnPairHandle extends MWHandle {
+
+	/**
+	 * This is the actual column pair.
+	 * It is built from the table, reference, and column pair names, below.
+	 */
+	private volatile ELColumnPair columnPair;
+
+	/**
+	 * The table, reference, and column pair names are transient. They
+	 * are used only to hold their values until #postProjectBuild()
+	 * is called and we can resolve the actual column pair.
+	 * We do not keep these in synch with the column pair itself because
+	 * we cannot know when the column pair has been renamed etc.
+	 */
+	private volatile String tableName;
+	private volatile String referenceName;
+	private volatile String columnPairName;
+
+	// ********** constructors **********
+
+	/**
+	 * default constructor - for TopLink use only
+	 */
+	private MWColumnPairHandle() {
+		super();
+	}
+
+	public MWColumnPairHandle(ELModel parent, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+	}
+
+	public MWColumnPairHandle(ELModel parent, ELColumnPair columnPair, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+		this.columnPair = columnPair;
+	}
+
+
+	// ********** instance methods **********
+
+	public ELColumnPair getColumnPair() {
+		return this.columnPair;
+	}
+
+	public void setColumnPair(ELColumnPair columnPair) {
+		this.columnPair = columnPair;
+	}
+
+	@Override
+	protected Node node() {
+		return this.getColumnPair();
+	}
+
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.columnPair == null) {
+			sb.append("null");
+		} else {
+			this.columnPair.toString(sb);
+		}
+	}
+
+	public MWColumnPairHandle setScrubber(NodeReferenceScrubber scrubber) {
+		this.setScrubberInternal(scrubber);
+		return this;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java
new file mode 100644
index 0000000..f6e5a02
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWHandle.java
@@ -0,0 +1,462 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.handles;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.persistence.tools.db.relational.ELNode;
+import org.eclipse.persistence.tools.utility.iterators.EmptyIterator;
+import org.eclipse.persistence.tools.utility.model.listener.ChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.CollectionChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.ListChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.PropertyChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.StateChangeListener;
+import org.eclipse.persistence.tools.utility.model.listener.TreeChangeListener;
+import org.eclipse.persistence.tools.utility.node.Node;
+import org.eclipse.persistence.tools.utility.node.Problem;
+
+/**
+ * Handles are used to isolate the painful bits of code
+ * necessary to correctly handle references to model objects.
+ *
+ * All handles should subclass this abstract class.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public abstract class MWHandle  implements ELNode {
+
+
+	/** Containment hierarchy. */
+	private ELNode parent;		// pseudo-final
+
+	/** This is used to synchronize the model when a node is removed. */
+	private NodeReferenceScrubber scrubber;		// pseudo-final
+
+	/** A handle is dirty when the path to its node changes. */
+	private volatile boolean dirty;
+
+	// ********** constructors **********
+
+	/**
+	 * default constructor - for TopLink use only
+	 */
+	protected MWHandle() {
+		super();
+		// a new object is dirty, by definition
+		this.dirty = true;
+	}
+
+	protected MWHandle(ELNode parent, NodeReferenceScrubber scrubber) {
+		this();
+		this.setParent(parent);
+		this.setScrubberInternal(scrubber);
+	}
+
+
+	// ********** containment hierarchy (parent/children) **********
+
+	@Override
+	public final Node getParent() {
+		return this.parent;
+	}
+
+	/**
+	 * Set the object's parent in the containment hierarchy.
+	 * Most objects must have a parent.
+	 */
+	public final void setParent(Node parent) {
+		if (parent == null) {
+			throw new NullPointerException();
+		}
+		this.parent = (ELNode) parent;
+	}
+
+	// handles do not have children
+	@Override
+	public final Iterator<Node> children() {
+		return EmptyIterator.instance();
+	}
+
+	// handles do not have children
+	public final void setChildBackpointers() {
+		// do nothing
+	}
+
+	@Override
+	public final boolean isDescendantOf(Node node) {
+		return (this == node) || this.parent.isDescendantOf(node);
+	}
+
+	@Override
+	public final void addBranchReferencesTo(Collection branchReferences) {
+		Node node = this.node();
+		if (node != null) {
+			branchReferences.add(new SimpleReference(this, node));
+		}
+	}
+
+	// handles do not have children
+	@Override
+	public final void addAllNodesTo(Collection nodes) {
+		nodes.add(this);
+	}
+
+
+	// ********** dirty flag support **********
+
+	@Override
+	public final boolean isDirtyBranch() {
+		return this.dirty;
+	}
+
+	@Override
+	public final void markBranchDirty() {
+		throw new IllegalStateException("handles shouldn't have children");
+	}
+
+	@Override
+	public final void markEntireBranchDirty() {
+		this.markDirty();
+	}
+
+	@Override
+	public final void cascadeMarkEntireBranchClean() {
+		this.dirty = false;
+	}
+
+	@Override
+	public final void markBranchCleanIfPossible() {
+		throw new IllegalStateException("handles shouldn't have children");
+	}
+
+	private void markDirty() {
+		this.dirty = true;
+		this.parent.markBranchDirty();
+	}
+
+
+	// ********** convenience methods **********
+
+	@Override
+	public final ELNode getMWParent() {
+		return this.parent;
+	}
+
+	// ********** model synchronization support **********
+
+	/**
+	 * Returns the node referenced by the handle.
+	 */
+	protected abstract Node node();
+
+	/**
+	 * If the handle's node has been renamed, or it is a descendant of
+	 * a node that has been renamed, the handle must mark its branch
+	 * dirty so that the handle is saved with the new name.
+	 */
+	@Override
+	public void nodeRenamed(Node node) {
+		if ((this.node() != null) && this.node().isDescendantOf(node)) {
+			this.markDirty();
+		}
+	}
+
+	/**
+	 * If the handle's node has been removed, or it is a descendant of
+	 * a node that has been removed, notify the scrubber.
+	 */
+	@Override
+	public final void nodeRemoved(Node removedNode) {
+		if ((this.node() != null) && this.node().isDescendantOf(removedNode)) {
+			this.scrubber.nodeReferenceRemoved(this.node(), this);
+		}
+	}
+
+	/**
+	 * Subclasses will probably implement something like
+	 * #setScrubber(NodeReferenceScrubber) that returns 'this'
+	 */
+	protected final void setScrubberInternal(NodeReferenceScrubber scrubber) {
+		if (scrubber == null) {
+			throw new NullPointerException();
+		}
+		this.scrubber = scrubber;
+	}
+
+
+	// ********** post-read methods **********
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 * 	that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a class or class sub-object
+	 * 	(attribute, method, etc.)
+	 */
+	public void resolveClassHandles() {
+		// do nothing
+	}
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 *  that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a descriptor or descriptor sub-object
+	 * 	(mapping, xml data field, etc.)
+	 */
+	public void resolveDescriptorHandles() {
+		// do nothing
+	}
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 *  that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a meta data object or sub-object
+	 * 	(field, schema component, etc.)
+	 */
+	public void resolveMetadataHandles() {
+		// do nothing
+	}
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 *  that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a meta data object or sub-object
+	 * 	(column, schema component, etc.)
+	 */
+	public void resolveColumnHandles() {
+		// do nothing
+	}
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 *  that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a meta data object or sub-object
+	 * 	(field, schema component, etc.)
+	 */
+	public void resolveReferenceHandles() {
+		// do nothing
+	}
+
+	/**
+	 * Override this method if there are objects in the hierarchy
+	 *  that depend on this handle being resolved before postProjectBuild().
+	 * Do not override unless the handle is for a meta data object or sub-object
+	 * 	(field, schema component, etc.)
+	 */
+	public void resolveMethodHandles() {
+		// do nothing
+	}
+
+	public void postProjectBuild() {
+		if (this.scrubber == null) {
+			throw new NullPointerException("This handle's 'scrubber' should have been set by its parent upon creation.");
+		}
+	}
+
+
+	// ********** display methods **********
+
+	/**
+	 * handles are not displayed
+	 */
+	@Override
+	public final String displayString() {
+		throw new UnsupportedOperationException();
+	}
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(" (");
+		this.toString(sb);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	public abstract void toString(StringBuffer sb);
+
+	// ************ Abstract, unused behavior *************
+
+	@Override
+	public Node root() {
+		return null;
+	}
+
+	@Override
+	public Validator getValidator() {
+		return null;
+	}
+
+	@Override
+	public void setValidator(Validator validator) {
+
+	}
+
+	@Override
+	public void validateBranch() {
+
+	}
+
+	@Override
+	public boolean validateBranchInternal() {
+		return false;
+	}
+
+	@Override
+	public ListIterator<Problem> branchProblems() {
+		return null;
+	}
+
+	@Override
+	public int branchProblemsSize() {
+		return 0;
+	}
+
+	@Override
+	public boolean hasBranchProblems() {
+		return false;
+	}
+
+	@Override
+	public boolean containsBranchProblem(Problem problem) {
+		return false;
+	}
+
+	@Override
+	public void rebuildBranchProblems() {
+
+	}
+
+	@Override
+	public void addBranchProblemsTo(List<Problem> branchProblems) {
+
+	}
+
+	@Override
+	public void clearAllBranchProblems() {
+
+	}
+
+	@Override
+	public boolean clearAllBranchProblemsInternal() {
+		return false;
+	}
+
+	@Override
+	public String comment() {
+		return null;
+	}
+
+	@Override
+	public void setComment(String comment) {
+
+	}
+
+	@Override
+	public void addChangeListener(ChangeListener listener) {
+
+	}
+
+	@Override
+	public void removeChangeListener(ChangeListener listener) {
+
+	}
+
+	@Override
+	public void addStateChangeListener(StateChangeListener listener) {
+
+	}
+
+	@Override
+	public void removeStateChangeListener(StateChangeListener listener) {
+
+	}
+
+	@Override
+	public void addPropertyChangeListener(String propertyName,
+			PropertyChangeListener listener) {
+
+	}
+
+	@Override
+	public void removePropertyChangeListener(String propertyName,
+			PropertyChangeListener listener) {
+	}
+
+	@Override
+	public void addCollectionChangeListener(String collectionName,
+			CollectionChangeListener listener) {
+
+	}
+
+	@Override
+	public void removeCollectionChangeListener(String collectionName,
+			CollectionChangeListener listener) {
+
+	}
+
+	@Override
+	public void addListChangeListener(String listName,
+			ListChangeListener listener) {
+	}
+
+	@Override
+	public void removeListChangeListener(String listName,
+			ListChangeListener listener) {
+	}
+
+	@Override
+	public void addTreeChangeListener(String treeName,
+			TreeChangeListener listener) {
+	}
+
+	@Override
+	public void removeTreeChangeListener(String treeName,
+			TreeChangeListener listener) {
+	}
+
+	// ********** member interface **********
+
+	/**
+	 * This interface defines the method called by a handle when the node the
+	 * handle references has been removed from the project. Typically the
+	 * handle's parent will implement an adapter that will call the appropriate
+	 * method to either remove or clear the handle. The handle itself will
+	 * continue to hold the reference node - it is up to the parent to
+	 * synchronize appropriately.
+	 */
+	public interface NodeReferenceScrubber {
+
+		/**
+		 * The specified node is no longer referenced by the specified handle.
+		 */
+		void nodeReferenceRemoved(Node node, MWHandle handle);
+
+		NodeReferenceScrubber NULL_INSTANCE = new NodeReferenceScrubber() {
+			@Override
+			public void nodeReferenceRemoved(Node node, MWHandle handle) {
+				// do nothing
+			}
+			@Override
+			public String toString() {
+				return "NullReferenceScrubber";
+			}
+		};
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWReferenceHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWReferenceHandle.java
new file mode 100644
index 0000000..38c4e89
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWReferenceHandle.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.handles;
+
+import org.eclipse.persistence.tools.db.relational.ELModel;
+import org.eclipse.persistence.tools.db.relational.ELReference;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * MWReferenceHandle is used to isolate the painful bits of code
+ * necessary to correctly handle references to MWReferences.
+ * Since a MWReference is nested within the XML file
+ * for a MWTable, we need to store a reference to a particular
+ * reference as a pair of instance variables:
+ *   - the name of the containing table
+ *   - the name of the reference
+ *
+ * This causes no end of pain when dealing with TopLink, property
+ * change listeners, backward-compatibility, etc.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class MWReferenceHandle extends MWHandle {
+
+	/**
+	 * This is the actual reference.
+	 * It is built from the table and reference names, below.
+	 */
+	private volatile ELReference reference;
+
+	/**
+	 * The table and reference names are transient. They
+	 * are used only to hold their values until postProjectBuild()
+	 * is called and we can resolve the actual reference.
+	 * We do not keep these in synch with the reference itself because
+	 * we cannot know when the reference has been renamed etc.
+	 */
+	private volatile String referenceTableName;
+	private volatile String referenceName;
+
+	// ********** constructors **********
+
+	/**
+	 * default constructor - for TopLink use only
+	 */
+	@SuppressWarnings("unused")
+	private MWReferenceHandle() {
+		super();
+	}
+
+	public MWReferenceHandle(ELModel parent, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+	}
+
+	public MWReferenceHandle(ELModel parent, ELReference reference, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+		this.reference = reference;
+	}
+
+
+	// ********** instance methods **********
+
+	public ELReference getReference() {
+		return this.reference;
+	}
+
+	public void setReference(ELReference reference) {
+		this.reference = reference;
+	}
+
+	@Override
+	protected Node node() {
+		return getReference();
+	}
+
+	public MWReferenceHandle setScrubber(NodeReferenceScrubber scrubber) {
+		this.setScrubberInternal(scrubber);
+		return this;
+	}
+
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.reference == null) {
+			sb.append("null");
+		} else {
+			this.reference.toString(sb);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWTableHandle.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWTableHandle.java
new file mode 100644
index 0000000..38fbe43
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/handles/MWTableHandle.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.handles;
+
+import org.eclipse.persistence.tools.db.relational.ELModel;
+import org.eclipse.persistence.tools.db.relational.ELTable;
+import org.eclipse.persistence.tools.utility.node.Node;
+
+/**
+ * MWTableHandle is used to handle a reference to a MWTable via a table name.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class MWTableHandle extends MWHandle {
+
+	/**
+	 * This is the actual table.
+	 * It is built from the table name, below.
+	 */
+	private volatile ELTable table;
+
+	/**
+	 * The table name is transient. It is used only to hold its value
+	 * until postProjectBuild() is called and we can resolve
+	 * the actual table. We do not keep it in synch with the table
+	 * itself because we cannot know when the table has been renamed etc.
+	 */
+	private volatile String tableName;
+
+	// ********** constructors **********
+
+	/**
+ 	 * default constructor - for TopLink use only
+ 	 */
+	@SuppressWarnings("unused")
+	private MWTableHandle() {
+		super();
+	}
+
+	public MWTableHandle(ELModel parent, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+	}
+
+	public MWTableHandle(ELModel parent, ELTable table, NodeReferenceScrubber scrubber) {
+		super(parent, scrubber);
+		this.table = table;
+	}
+
+
+	// ********** instance methods **********
+
+	public ELTable getTable() {
+		return this.table;
+	}
+
+	public void setTable(ELTable table) {
+		this.table = table;
+	}
+
+	@Override
+	protected Node node() {
+		return getTable();
+	}
+
+	public MWTableHandle setScrubber(NodeReferenceScrubber scrubber) {
+		this.setScrubberInternal(scrubber);
+		return this;
+	}
+
+	@Override
+	public void toString(StringBuffer sb) {
+		if (this.table == null) {
+			sb.append("null");
+		} else {
+			this.table.toString(sb);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
new file mode 100644
index 0000000..21501ec
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/AbstractJDBCTypeToJavaTypeDeclarationMapping.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Node;
+
+/**
+ * Common behavior(?).
+ * Neither instance variable should ever be null.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+abstract class AbstractJDBCTypeToJavaTypeDeclarationMapping extends AbstractNode {
+
+	JDBCType jdbcType;
+	JavaTypeDeclaration javaTypeDeclaration;
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the mapping is read from an XML file
+	 */
+	AbstractJDBCTypeToJavaTypeDeclarationMapping(JDBCTypeRepository repository, Node node) throws CorruptXMLException {
+		super(repository);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new mapping (which shouldn't happen very often,
+	 * since all the typical mappings have already been built...)
+	 */
+	AbstractJDBCTypeToJavaTypeDeclarationMapping(JDBCTypeRepository repository, JDBCType jdbcType, String javaClassName, int arrayDepth) {
+		super(repository);
+		if (jdbcType == null) {
+			throw new NullPointerException();
+		}
+		this.jdbcType = jdbcType;
+		this.javaTypeDeclaration = new JavaTypeDeclaration(this, javaClassName, arrayDepth);
+	}
+
+
+	// ********** accessors **********
+
+	private JDBCTypeRepository getJDBCTypeRepository() {
+		return  (JDBCTypeRepository) this.getParent();
+	}
+
+	public JDBCType getJDBCType() {
+		return this.jdbcType;
+	}
+
+	public JavaTypeDeclaration getJavaTypeDeclaration() {
+		return this.javaTypeDeclaration;
+	}
+
+
+	// ********** queries **********
+
+	private JDBCType jdbcTypeNamed(String jdbcTypeName) {
+		return this.getJDBCTypeRepository().jdbcTypeNamed(jdbcTypeName);
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		try {
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+		} catch (IllegalArgumentException ex) {
+			throw new CorruptXMLException(ex);
+		}
+		this.javaTypeDeclaration = new JavaTypeDeclaration(this, XMLTools.child(node, "java-type-declaration"));
+	}
+
+	/**
+	 * Subclasses decide the order the child nodes are written.
+	 */
+	abstract void write(Node node);
+
+	void writeJDBCType(Node node) {
+		XMLTools.addSimpleTextNode(node, "jdbc-type", this.jdbcType.getName());
+	}
+
+	void writeJavaTypeDeclaration(Node node) {
+		this.javaTypeDeclaration.write(node.appendChild(node.getOwnerDocument().createElement("java-type-declaration")));
+	}
+
+	// ********** printing and displaying **********
+
+	public abstract void displayStringOn(StringBuffer sb);
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		StringBuffer sb = new StringBuffer();
+		this.displayStringOn(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(java.lang.StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		this.displayStringOn(sb);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/CorruptXMLException.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/CorruptXMLException.java
new file mode 100644
index 0000000..9553c75
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/CorruptXMLException.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+/**
+ * A CorruptFileException is thrown whenever a "corrupt" XML file is read in.
+ *
+ * @version 2.5
+ */
+public class CorruptXMLException extends Exception {
+
+	/**
+	 * Construct an exception with no message.
+	 */
+	public CorruptXMLException() {
+		super();
+	}
+
+	/**
+	 * Construct an exception with the specified message.
+	 */
+	public CorruptXMLException(String message) {
+		super(message);
+	}
+
+	/**
+	 * Construct an exception chained to the specified cause.
+	 */
+	public CorruptXMLException(Throwable cause) {
+		super(cause);
+	}
+
+	/**
+	 * Construct an exception with the specified message and
+	 * chained to the specified cause.
+	 */
+	public CorruptXMLException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java
new file mode 100644
index 0000000..fe4933e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatform.java
@@ -0,0 +1,705 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * A database platform holds all the settings for a specific database platform (e.g. Oracle, MS SQL
+ * Server). This includes whether the platform supports certain features used by TopLink (e.g.
+ * native sequencing) and the various database types and their corresponding JDBC types.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class DatabasePlatform extends AbstractNode {
+
+	/**
+	 * a name uniquely identifying the platform within a
+	 * database platform repository
+	 */
+	private String name;
+		public static final String NAME_PROPERTY = "name";
+
+	/**
+	 * this is the short file name - the directory is determined
+	 * by the parent repository;
+	 * like the name, above, this must also be unique within the repository
+	 */
+	private String shortFileName;
+		public static final String SHORT_FILE_NAME_PROPERTY = "shortFileName";
+
+	/**
+	 * store this as a string (as opposed to the actual class) because users
+	 * can supply their own and it might not be on the classpath
+	 */
+	private String runtimePlatformClassName;
+		public static final String RUNTIME_PLATFORM_CLASS_NAME_PROPERTY = "runtimePlatformClassName";
+
+	/**
+	 * whether the platform supports "native" sequencing, as opposed to
+	 * using a "sequence" table
+	 * (Oracle variants have SEQUENCEs; SQL Server variants have
+	 * IDENTITY fields; Informix has SERIAL fields)
+	 */
+	private boolean supportsNativeSequencing;
+		public static final String SUPPORTS_NATIVE_SEQUENCING_PROPERTY = "supportsNativeSequencing";
+
+	/**
+	 * whether the platform supports the IDENTITY clause in a column definition
+	 * (SQL Server variants only)
+	 */
+	private boolean supportsIdentityClause;
+		public static final String SUPPORTS_IDENTITY_CLAUSE_PROPERTY = "supportsIdentityClause";
+
+	/**
+	 * whether the platform supports returning on an update/insert natively
+	 */
+	private boolean supportsNativeReturning;
+		public static final String SUPPORTS_NATIVE_RETURNING_PROPERTY = "supportsNativeReturning";
+
+	/**
+	 * collection of the database platform-specific datatypes
+	 * (e.g. VARCHAR2, NUMBER)
+	 */
+	private Collection<DatabaseType> databaseTypes;
+		public static final String DATABASE_TYPES_COLLECTION = "databaseTypes";
+
+	/**
+	 * mappings of all the JDBC types to the database platform-specific datatypes
+	 * (e.g. java.sql.Types.INTEGER maps to the Oracle NUMBER)
+	 */
+	private Collection<JDBCTypeToDatabaseTypeMapping> jdbcTypeToDatabaseTypeMappings;
+		public static final String JDBC_TYPE_TO_DATABASE_TYPE_MAPPINGS_COLLECTION = "jdbcTypeToDatabaseTypeMappings";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the platform is read from an XML file
+	 */
+	DatabasePlatform(DatabasePlatformRepository repository, File file) throws CorruptXMLException {
+		super(repository);
+		this.read(file);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new platform (which shouldn't happen very often,
+	 * since all the typical platforms have already been built and
+	 * stored in XML files...)
+	 */
+	DatabasePlatform(DatabasePlatformRepository repository, String name, String shortFileName) {
+		super(repository);
+		this.name = name;
+		this.shortFileName = shortFileName;
+		this.initializeJDBCTypeToDatabaseTypeMappings();
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#initialize()
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.runtimePlatformClassName = this.defaultRuntimePlatformClassName();
+		this.supportsNativeSequencing = false;
+		this.supportsNativeReturning = false;
+		this.supportsIdentityClause = false;
+		this.databaseTypes = new Vector<DatabaseType>();
+		this.jdbcTypeToDatabaseTypeMappings = new Vector<JDBCTypeToDatabaseTypeMapping>();
+	}
+
+	private String defaultRuntimePlatformClassName() {
+		return "org.eclipse.persistence.platform.database.DatabasePlatform";	// this is the runtime default
+	}
+
+	/**
+	 * build an empty mapping for every JDBC type in the JDBC type repository
+	 */
+	private void initializeJDBCTypeToDatabaseTypeMappings() {
+		for (Iterator<JDBCType> stream = this.jdbcTypeRepository().jdbcTypes(); stream.hasNext(); ) {
+			this.jdbcTypeToDatabaseTypeMappings.add(new JDBCTypeToDatabaseTypeMapping(this, stream.next()));
+		}
+	}
+
+
+	// ********** accessors **********
+
+	public DatabasePlatformRepository getRepository() {
+		return  (DatabasePlatformRepository) this.getParent();
+	}
+
+
+	// ***** name
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		if ((name != null) && name.equals(this.name)) {
+			return;
+		}
+		this.getRepository().checkPlatformName(name);
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+
+	// ***** short file name
+	public String getShortFileName() {
+		return this.shortFileName;
+	}
+
+	public void setShortFileName(String shortFileName) {
+		if ((shortFileName != null) && shortFileName.equals(this.shortFileName)) {
+			return;
+		}
+		this.getRepository().checkPlatformShortFileName(shortFileName);
+		Object old = this.shortFileName;
+		this.shortFileName = shortFileName;
+		this.firePropertyChanged(SHORT_FILE_NAME_PROPERTY, old, shortFileName);
+	}
+
+
+	// ***** runtime platform class name
+	public String getRuntimePlatformClassName() {
+		return this.runtimePlatformClassName;
+	}
+
+	public void setRuntimePlatformClassName(String runtimePlatformClassName) {
+		if ((runtimePlatformClassName == null) || (runtimePlatformClassName.length() == 0)) {
+			throw new IllegalArgumentException("run-time platform class name is required");
+		}
+		Object old = runtimePlatformClassName;
+		this.runtimePlatformClassName = runtimePlatformClassName;
+		this.firePropertyChanged(RUNTIME_PLATFORM_CLASS_NAME_PROPERTY, old, runtimePlatformClassName);
+	}
+
+	// ***** supports native returning
+	public boolean supportsNativeReturning() {
+		return this.supportsNativeReturning;
+	}
+
+	public void setSupportsNativeReturning(boolean supportNativeReturning) {
+		boolean old = this.supportsNativeReturning;
+		this.supportsNativeReturning = supportNativeReturning;
+		this.firePropertyChanged(SUPPORTS_NATIVE_RETURNING_PROPERTY, old, supportNativeReturning);
+	}
+
+	// ***** supports native sequencing
+	public boolean supportsNativeSequencing() {
+		return this.supportsNativeSequencing;
+	}
+
+	public void setSupportsNativeSequencing(boolean supportsNativeSequencing) {
+		boolean old = this.supportsNativeSequencing;
+		this.supportsNativeSequencing = supportsNativeSequencing;
+		this.firePropertyChanged(SUPPORTS_NATIVE_SEQUENCING_PROPERTY, old, supportsNativeSequencing);
+
+		// if we don't support "native" sequencing, then we can't support the IDENTITY clause
+		if ( ! supportsNativeSequencing) {
+			this.setSupportsIdentityClause(false);
+		}
+	}
+
+
+	// ***** supports IDENTITY clause
+	public boolean supportsIdentityClause() {
+		return this.supportsIdentityClause;
+	}
+
+	public void setSupportsIdentityClause(boolean supportsIdentityClause) {
+		boolean old = this.supportsIdentityClause;
+		this.supportsIdentityClause = supportsIdentityClause;
+		this.firePropertyChanged(SUPPORTS_IDENTITY_CLAUSE_PROPERTY, old, supportsIdentityClause);
+
+		// if we support the IDENTITY clause, then we must support "native" sequencing
+		if (supportsIdentityClause) {
+			this.setSupportsNativeSequencing(true);
+		}
+	}
+
+
+	// ***** database types
+	public Iterator<DatabaseType> databaseTypes() {
+		return new CloneIterator<DatabaseType>(this.databaseTypes) {
+			@Override
+			protected void remove(DatabaseType current) {
+				DatabasePlatform.this.removeDatabaseType(current);
+			}
+		};
+	}
+
+	public int databaseTypesSize() {
+		return this.databaseTypes.size();
+	}
+
+	public DatabaseType addDatabaseType(String typeName) {
+		this.checkDatabaseTypeName(typeName);
+		return this.addDatabaseType(new DatabaseType(this, typeName));
+	}
+
+	private DatabaseType addDatabaseType(DatabaseType type) {
+		this.addItemToCollection(type, this.databaseTypes, DATABASE_TYPES_COLLECTION);
+		return type;
+	}
+
+	public void removeDatabaseType(DatabaseType type) {
+		this.removeItemFromCollection(type, this.databaseTypes, DATABASE_TYPES_COLLECTION);
+		this.databaseTypeRemoved(type);
+	}
+
+	private void databaseTypeRemoved(DatabaseType removedType) {
+		synchronized (this.jdbcTypeToDatabaseTypeMappings) {
+			for (JDBCTypeToDatabaseTypeMapping mapping : this.jdbcTypeToDatabaseTypeMappings) {
+				if (mapping.getDatabaseType() == removedType) {
+					mapping.setDatabaseType(null);
+				}
+			}
+		}
+	}
+
+	public void removeDatabaseTypes(Collection<DatabaseType> types) {
+		this.removeItemsFromCollection(types, this.databaseTypes, DATABASE_TYPES_COLLECTION);
+		this.databaseTypesRemoved(types);
+	}
+
+	private void databaseTypesRemoved(Collection<DatabaseType> removedTypes) {
+		for (DatabaseType type : removedTypes) {
+			this.databaseTypeRemoved(type);
+		}
+	}
+
+	public void removeDatabaseTypes(Iterator<DatabaseType> types) {
+		this.removeDatabaseTypes(CollectionTools.collection(types));
+	}
+
+
+	// ***** JDBC type to database type mappings
+	public Iterator<JDBCTypeToDatabaseTypeMapping> jdbcTypeToDatabaseTypeMappings() {
+		return new CloneIterator<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings);
+	}
+
+	public int jdbcTypeToDatabaseTypeMappingsSize() {
+		return this.jdbcTypeToDatabaseTypeMappings.size();
+	}
+
+	/**
+	 * adding and removing mappings is PRIVATE;
+	 * these are done only in response to changes to the JDBC type repository
+	 */
+	private JDBCTypeToDatabaseTypeMapping addJDBCTypeToDatabaseTypeMapping(JDBCType jdbcType) {
+		return this.addJDBCTypeToDatabaseTypeMapping(new JDBCTypeToDatabaseTypeMapping(this, jdbcType));
+	}
+
+	/**
+	 * adding and removing mappings is PRIVATE;
+	 * these are done only in response to changes to the JDBC type repository
+	 */
+	private JDBCTypeToDatabaseTypeMapping addJDBCTypeToDatabaseTypeMapping(JDBCTypeToDatabaseTypeMapping mapping) {
+		this.addItemToCollection(mapping, this.jdbcTypeToDatabaseTypeMappings, JDBC_TYPE_TO_DATABASE_TYPE_MAPPINGS_COLLECTION);
+		return mapping;
+	}
+
+	/**
+	 * adding and removing mappings is PRIVATE;
+	 * these are done only in response to changes to the JDBC type repository
+	 */
+	private Iterator<JDBCTypeToDatabaseTypeMapping> internalJDBCTypeToDatabaseTypeMappings() {
+		return new CloneIterator<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings) {
+			@Override
+			protected void remove(JDBCTypeToDatabaseTypeMapping current) {
+				DatabasePlatform.this.removeJDBCTypeToDatabaseTypeMapping(current);
+			}
+		};
+	}
+
+	/**
+	 * adding and removing mappings is PRIVATE;
+	 * these are done only in response to changes to the JDBC type repository
+	 */
+	void removeJDBCTypeToDatabaseTypeMapping(JDBCTypeToDatabaseTypeMapping mapping) {
+		this.removeItemFromCollection(mapping, this.jdbcTypeToDatabaseTypeMappings, JDBC_TYPE_TO_DATABASE_TYPE_MAPPINGS_COLLECTION);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * this is how a database field resolves its database type
+	 * when the database field is read in from an XML file
+	 */
+	public DatabaseType databaseTypeNamed(String databaseTypeName) {
+		synchronized (this.databaseTypes) {
+			for (DatabaseType databaseType : this.databaseTypes) {
+				if (databaseType.getName().equals(databaseTypeName)) {
+					return databaseType;
+				}
+			}
+			throw new IllegalArgumentException("missing database type named: "
+					+ databaseTypeName + " (platform: " + this.name + ")");
+		}
+	}
+
+	public boolean containsDatabaseTypeNamed(String databaseTypeName) {
+		synchronized (this.databaseTypes) {
+			for (DatabaseType databaseType : this.databaseTypes) {
+				if (databaseType.getName().equals(databaseTypeName)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private JDBCTypeRepository jdbcTypeRepository() {
+		return this.getRepository().getJDBCTypeRepository();
+	}
+
+	private JDBCType jdbcTypeForCode(int jdbcTypeCode) {
+		return this.jdbcTypeRepository().jdbcTypeForCode(jdbcTypeCode);
+	}
+
+	JDBCType jdbcTypeNamed(String jdbcTypeName) {
+		return this.jdbcTypeRepository().jdbcTypeNamed(jdbcTypeName);
+	}
+
+	public DatabaseType defaultDatabaseType() {
+		return this.databaseTypeFor(this.jdbcTypeRepository().getDefaultJDBCType());
+	}
+
+	/**
+	 * Returns the database type from "this" platform that is a reasonable
+	 * facsimile of the specified database type from some "other" platform;
+	 * used for converting database tables from one platform to another
+	 */
+	public DatabaseType databaseTypeFor(DatabaseType otherType) {
+		// if there is a type on this platform with the exact same name, use it;
+		// the platforms might simply be variants of each other (e.g. Sybase vs. MS SQL Server)
+		try {
+			return this.databaseTypeNamed(otherType.getName());
+		} catch (IllegalArgumentException ex) {
+			// if there is no direct match, convert to a JDBC type then to a database type for this platform
+			return this.databaseTypeFor(otherType.getJDBCType());
+		}
+	}
+
+	private Iterator<String> databaseTypeNames() {
+		return new TransformationIterator<String, DatabaseType>(this.databaseTypes()) {
+			@Override
+			protected String transform(DatabaseType next) {
+				return next.getName();
+			}
+		};
+	}
+
+	/**
+	 * this is only used during a read, when we are checking for duplicates
+	 */
+	private boolean maps(JDBCType type) {
+		for (JDBCTypeToDatabaseTypeMapping mapping : this.jdbcTypeToDatabaseTypeMappings) {
+			if (mapping.getJDBCType() == type) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	// * Returns a database type for a given JDBC type or code **********
+
+	/**
+	 * every platform will have every JDBC type mapped to a database type
+	 */
+	private JDBCTypeToDatabaseTypeMapping jdbcTypeToDatabaseTypeMappingFor(JDBCType jdbcType) {
+		synchronized (this.jdbcTypeToDatabaseTypeMappings) {
+			for (JDBCTypeToDatabaseTypeMapping mapping : this.jdbcTypeToDatabaseTypeMappings) {
+				if (mapping.maps(jdbcType)) {
+					return mapping;
+				}
+			}
+			throw new IllegalStateException("JDBC type to database type mapping is missing: "
+					+ jdbcType.getName() + " (platform: " + this.name + ")");
+		}
+	}
+
+	/**
+	 * every platform will have every JDBC type mapped to a database type
+	 */
+	private DatabaseType databaseTypeFor(JDBCType jdbcType) {
+		return this.jdbcTypeToDatabaseTypeMappingFor(jdbcType).getDatabaseType();
+	}
+
+	/**
+	 * every platform will have every JDBC type mapped to a database type
+	 */
+	public DatabaseType databaseTypeForJDBCTypeCode(int jdbcTypeCode) {
+		return this.databaseTypeFor(this.jdbcTypeForCode(jdbcTypeCode));
+	}
+
+
+	// * Returns a database type for a given Java type declaration **********
+
+	/**
+	 * Returns whether the specified Java type declaration has a corresponding
+	 * datatype; this can be used to determine whether a
+	 * Java class can be mapped with a direct-to-field mapping
+	 * (or a direct collection mapping), as opposed to needing its
+	 * own descriptor
+	 */
+	public boolean javaTypeDeclarationCanBeMappedToDatabaseType(String javaClassName, int arrayDepth) {
+		// if there is a JDBC type for the Java type declaration, then we have a database type...
+		return this.jdbcTypeRepository().javaTypeDeclarationCanBeMappedToJDBCType(javaClassName, arrayDepth);
+	}
+
+	/**
+	 * get the JDBC type for the specified type declaration, then
+	 * get the database type for that JDBC type
+	 */
+	public DatabaseType databaseTypeForJavaTypeDeclaration(String javaClassName, int arrayDepth) {
+		return this.databaseTypeFor(this.jdbcTypeRepository().jdbcTypeForJavaTypeDeclaration(javaClassName, arrayDepth));
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.mappingsmodel.AbstractNodeModel#addChildrenTo(java.util.List)
+	 */
+	@Override
+	protected void addChildrenTo(List<org.eclipse.persistence.tools.utility.node.Node> children) {
+		super.addChildrenTo(children);
+		synchronized (this.databaseTypes) { children.addAll(this.databaseTypes); }
+		synchronized (this.jdbcTypeToDatabaseTypeMappings) { children.addAll(this.jdbcTypeToDatabaseTypeMappings); }
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.mappingsmodel.AbstractNodeModel#nodeRemoved(org.eclipse.persistence.tools.workbench.utility.Node)
+	 */
+	@Override
+	public void nodeRemoved(org.eclipse.persistence.tools.utility.node.Node node) {
+		super.nodeRemoved(node);
+		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = this.internalJDBCTypeToDatabaseTypeMappings(); stream.hasNext(); ) {
+			if (stream.next().getJDBCType() == node) {
+				stream.remove();
+				break;	// there should be only one...
+			}
+		}
+	}
+
+	void jdbcTypeAdded(JDBCType newJDBCType) {
+		this.addJDBCTypeToDatabaseTypeMapping(newJDBCType);
+	}
+
+	/**
+	 * copy all the settings from the original platform
+	 * to this, newly-created, platform
+	 */
+	void cloneFrom(DatabasePlatform originalPlatform) {
+		// the name and shortFileName have been set by the time we get here
+		this.runtimePlatformClassName = originalPlatform.getRuntimePlatformClassName();
+		this.supportsNativeSequencing = originalPlatform.supportsNativeSequencing();
+		this.supportsNativeReturning = originalPlatform.supportsNativeReturning();
+		this.supportsIdentityClause = originalPlatform.supportsIdentityClause();
+		for (Iterator<DatabaseType> stream = originalPlatform.databaseTypes(); stream.hasNext(); ) {
+			DatabaseType originalType = stream.next();
+			DatabaseType cloneType = this.addDatabaseType(originalType.getName());
+			cloneType.cloneFrom(originalType);
+		}
+		// the JDBC mappings have been pre-built by the time we get here
+		for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = originalPlatform.jdbcTypeToDatabaseTypeMappings(); stream.hasNext(); ) {
+			JDBCTypeToDatabaseTypeMapping originalMapping = stream.next();
+			JDBCTypeToDatabaseTypeMapping cloneMapping = this.jdbcTypeToDatabaseTypeMappingFor(originalMapping.getJDBCType());
+			cloneMapping.cloneFrom(originalMapping);
+		}
+	}
+
+	/**
+	 * disallow duplicate type names within a single platform
+	 */
+	private void checkDatabaseType(DatabaseType databaseType) {
+		this.checkDatabaseTypeName(databaseType.getName());
+	}
+
+	/**
+	 * disallow duplicate type names within a single platform
+	 */
+	void checkDatabaseTypeName(String databaseTypeName) {
+		if ((databaseTypeName == null) || (databaseTypeName.length() == 0)) {
+			throw new IllegalArgumentException("database type name is required");
+		}
+		if (CollectionTools.contains(this.databaseTypeNames(), databaseTypeName)) {
+			throw new IllegalArgumentException("duplicate database type name: " + databaseTypeName);
+		}
+	}
+
+
+	// ********** i/o **********
+
+	// ***** read
+	private void read(File file) throws CorruptXMLException {
+		this.shortFileName = file.getName();
+		Document doc = XMLTools.parse(file);
+		Node root = XMLTools.child(doc, "database-platform");
+		if (root == null) {
+			throw new CorruptXMLException("missing root node: database-platform (" + file.getPath() + ")");
+		}
+
+		this.name = XMLTools.childTextContent(root, "name", null);
+		if ((this.name == null) || (this.name.length() == 0)) {
+			throw new CorruptXMLException("name is required (" + file.getPath() + ")");
+		}
+
+		this.runtimePlatformClassName = XMLTools.childTextContent(root, "runtime-platform-class", null);
+		if ((this.runtimePlatformClassName == null) || (this.runtimePlatformClassName.length() == 0)) {
+			throw this.buildCorruptXMLException("run-time platform class name is required");
+		}
+
+		this.supportsNativeSequencing = XMLTools.childBooleanContent(root, "supports-native-sequencing", false);
+		this.supportsNativeReturning = XMLTools.childBooleanContent(root, "supports-native-returning", false);
+		this.supportsIdentityClause = XMLTools.childBooleanContent(root, "supports-identity-clause", false);
+		if (this.supportsIdentityClause && ( ! this.supportsNativeSequencing)) {
+			throw this.buildCorruptXMLException("platform must support native sequencing if it supports the IDENTITY clause");
+		}
+
+		this.readDatabaseTypeNodes(XMLTools.child(root, "database-types"));
+
+		// wait until the database types have been read in before building the JDBC mappings
+		this.readJDBCMappingNodes(XMLTools.child(root, "jdbc-mappings"));
+	}
+
+	private void readDatabaseTypeNodes(Node databaseTypesNode) throws CorruptXMLException {
+		Node[] databaseTypeNodes = XMLTools.children(databaseTypesNode, "database-type");
+		int len = databaseTypeNodes.length;
+		for (int i = 0; i < len; i++) {
+			DatabaseType databaseType = new DatabaseType(this, databaseTypeNodes[i]);
+			try {
+				this.checkDatabaseType(databaseType);	// check for duplicates
+			} catch (IllegalArgumentException ex) {
+				throw this.buildCorruptXMLException(ex);
+			}
+			this.databaseTypes.add(databaseType);
+		}
+	}
+
+	private void readJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
+		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-mapping");
+		int len = mappingNodes.length;
+		for (int i = 0; i < len; i++) {
+			JDBCTypeToDatabaseTypeMapping mapping = new JDBCTypeToDatabaseTypeMapping(this, mappingNodes[i]);
+			// check for duplicates
+			if (this.maps(mapping.getJDBCType())) {
+				throw this.buildCorruptXMLException("duplicate JDBC to database type mapping: " + mapping);
+			}
+			this.jdbcTypeToDatabaseTypeMappings.add(mapping);
+		}
+		// at this point, the mappings all have legitimate JDBC types and
+		// there are no duplicates; so we just need to make sure *every* JDBC type has been mapped
+		if (this.jdbcTypeToDatabaseTypeMappings.size() != this.jdbcTypeRepository().jdbcTypesSize()) {
+			throw this.buildCorruptXMLException("missing JDBC to database type mappings (number of mappings: " + this.jdbcTypeToDatabaseTypeMappings.size()
+					+ " - number of JDBC types: " + this.jdbcTypeRepository().jdbcTypesSize() + ")");
+		}
+	}
+
+	/**
+	 * tack the platform on to the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(String message) {
+		return new CorruptXMLException(message + " (platform: " + this.name + ")");
+	}
+
+	/**
+	 * tack the platform on to the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(Throwable t) {
+		return new CorruptXMLException("platform: " + this.name, t);
+	}
+
+	// ***** write
+	void write(File platformsDirectory) {
+		if (this.isCleanBranch()) {
+			return;
+		}
+		Document document = XMLTools.newDocument();
+		Node root = document.createElement("database-platform");
+		document.appendChild(root);
+		XMLTools.addSimpleTextNode(root, "name", this.name);
+		XMLTools.addSimpleTextNode(root, "runtime-platform-class", this.runtimePlatformClassName);
+		XMLTools.addSimpleTextNode(root, "supports-native-sequencing", this.supportsNativeSequencing, false);
+		XMLTools.addSimpleTextNode(root, "supports-native-returning", this.supportsNativeReturning, false);
+		XMLTools.addSimpleTextNode(root, "supports-identity-clause", this.supportsIdentityClause, false);
+
+		this.writeDatabaseTypeNodes(root.appendChild(document.createElement("database-types")));
+		this.writeJDBCMappingNodes(root.appendChild(document.createElement("jdbc-mappings")));
+
+		XMLTools.print(document, new File(platformsDirectory, this.shortFileName));
+		this.markEntireBranchClean();
+	}
+
+	private void writeDatabaseTypeNodes(Node databaseTypesNode) {
+		Document document = databaseTypesNode.getOwnerDocument();
+		synchronized (this.databaseTypes) {
+			for (Iterator<DatabaseType> stream = new TreeSet<DatabaseType>(this.databaseTypes).iterator(); stream.hasNext(); ) {
+				Node databaseTypeNode = document.createElement("database-type");
+				databaseTypesNode.appendChild(databaseTypeNode);
+				stream.next().write(databaseTypeNode);
+			}
+		}
+	}
+
+	private void writeJDBCMappingNodes(Node mappingsNode) {
+		Document document = mappingsNode.getOwnerDocument();
+		synchronized (this.jdbcTypeToDatabaseTypeMappings) {
+			for (Iterator<JDBCTypeToDatabaseTypeMapping> stream = new TreeSet<JDBCTypeToDatabaseTypeMapping>(this.jdbcTypeToDatabaseTypeMappings).iterator(); stream.hasNext(); ) {
+				Node mappingNode = document.createElement("jdbc-mapping");
+				mappingsNode.appendChild(mappingNode);
+				stream.next().write(mappingNode);
+			}
+		}
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		sb.append(this.name);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java
new file mode 100644
index 0000000..c18d5a1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabasePlatformRepository.java
@@ -0,0 +1,658 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.FileTools;
+import org.eclipse.persistence.tools.utility.HashBag;
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * This is a repository of all the database platforms in the platforms resource directory. We also
+ * hold on to the JDBC type repository.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class DatabasePlatformRepository
+	extends AbstractNode
+{
+	/** something worth displaying */
+	private String name;
+		public static final String NAME_PROPERTY = "name";
+
+	/** the file that holds the platform repository settings and the JDBC type repository */
+	private File file;
+		public static final String FILE_PROPERTY = "file";
+
+	/** the database platforms */
+	private Collection<DatabasePlatform> platforms;
+		public static final String PLATFORMS_COLLECTION = "platforms";
+
+	/** the default database platform */
+	private DatabasePlatform defaultPlatform;
+		public static final String DEFAULT_PLATFORM_PROPERTY = "defaultPlatform";
+
+	/** used to map Java and JDBC types to each other */
+	private JDBCTypeRepository jdbcTypeRepository;
+		// the JDBC type repository is never replaced once the platform repository is built
+
+	/**
+	 * store the file names, so we can determine what to delete on save;
+	 * this is transient and for internal use only
+	 */
+	private Collection<String> originalPlatformShortFileNames;
+
+	/**
+	 * store the original file when it is renamed (but not moved),
+	 * so we can delete it on save;
+	 * this is transient and for internal use only
+	 */
+	private File originalFile;
+
+	/**
+	 * the name of the directory that holds the platform XML files,
+	 * relative to the repository file's location
+	 */
+	private static final String PLATFORMS_DIRECTORY_NAME = "platforms";
+
+	/**
+	 * the name of the default database platform repository file,
+	 * it should be on the classpath
+	 */
+	private static final String DEFAULT_PLATFORM_REPOSITORY_FILE_NAME = "platforms.dpr";
+
+	/**
+	 * the default database platform repository, built from the file
+	 * named above
+	 */
+	private static DatabasePlatformRepository defaultRepository;
+
+	// ********** static methods **********
+
+	/**
+	 * Returns the default database platform repository, which is built
+	 * from the file platforms.dpr found on the classpath
+	 */
+	public static DatabasePlatformRepository getDefault() {
+		if (defaultRepository == null) {
+			defaultRepository = buildDefault();
+		}
+		return defaultRepository;
+	}
+
+	private static DatabasePlatformRepository buildDefault() {
+		try {
+			return new DatabasePlatformRepository(buildDefaultFile());
+		} catch (CorruptXMLException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	private static File buildDefaultFile() {
+		try {
+			return FileTools.resourceFile("/" + DEFAULT_PLATFORM_REPOSITORY_FILE_NAME);
+		} catch (URISyntaxException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * (when reading in an existing repository)
+	 * clients must specify where we find the file...
+	 */
+	public DatabasePlatformRepository(File file) throws CorruptXMLException {
+		super(null);
+		if (file == null) {
+			throw new NullPointerException();
+		}
+		this.file = file;
+		this.read();
+	}
+
+	/**
+	 * ...or clients must specify the name of the repository
+	 * (when building one from scratch)
+	 */
+	public DatabasePlatformRepository(String name) {
+		super(null);
+		if (name == null) {
+			throw new NullPointerException();
+		}
+		this.name = name;
+		this.jdbcTypeRepository = new JDBCTypeRepository(this);
+		this.originalPlatformShortFileNames = Collections.emptySet();
+	}
+
+
+	// ********** initialization **********
+
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.platforms = new Vector<DatabasePlatform>();
+	}
+
+
+	@Override
+	protected void checkParent(org.eclipse.persistence.tools.utility.node.Node parentNode) {
+	}
+
+	// ********** accessors **********
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		if (name == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+
+	/**
+	 * this will only be null on a newly-created, unsaved repository
+	 */
+	public File getFile() {
+		return this.file;
+	}
+
+	public void setFile(File file) {
+		if (file == null) {
+			throw new NullPointerException();
+		}
+		File old = this.file;
+		this.file = file;
+		this.firePropertyChanged(FILE_PROPERTY, old, file);
+
+		if ((old != null) && old.exists()) {
+			if (old.getParentFile().equals(file.getParentFile())) {
+				// if the file was renamed but not moved, save the original for later deletion
+				if ( ! old.getName().equals(file.getName())) {
+					this.originalFile = old;
+				}
+			} else {
+				// if the location of the file has changed, mark everything dirty...
+				this.markEntireBranchDirty();
+				// ...and clear out the original file names, since we won't be deleting them on save
+				this.originalPlatformShortFileNames = Collections.emptySet();
+			}
+		}
+	}
+
+
+	public Iterator<DatabasePlatform> platforms() {
+		return new CloneIterator<DatabasePlatform>(this.platforms) {
+			@Override
+			protected void remove(DatabasePlatform current) {
+				DatabasePlatformRepository.this.removePlatform(current);
+			}
+		};
+	}
+
+	public int platformsSize() {
+		return this.platforms.size();
+	}
+
+	/**
+	 * the file name is the "short" file name - it should not include the directory;
+	 * since the file name is no longer derived from the platform name,
+	 * we need to specify both the name of the platform and where
+	 * it will be stored, both of which will be checked for uniqueness
+	 */
+	public DatabasePlatform addPlatform(String platformName, String platformShortFileName) {
+		this.checkPlatform(platformName, platformShortFileName);
+		return this.addPlatform(new DatabasePlatform(this, platformName, platformShortFileName));
+	}
+
+	private DatabasePlatform addPlatform(DatabasePlatform platform) {
+		this.addItemToCollection(platform, this.platforms, PLATFORMS_COLLECTION);
+		// the repository itself is not "dirty", but its branch is
+		this.markBranchDirty();
+		if (this.defaultPlatform == null) {
+			this.setDefaultPlatform(platform);
+		}
+		return platform;
+	}
+
+	public void removePlatform(DatabasePlatform platform) {
+		this.removeItemFromCollection(platform, this.platforms, PLATFORMS_COLLECTION);
+		// the repository itself is not "dirty", but its branch is
+		this.markBranchDirty();
+		this.resetDefaultPlatform();
+	}
+
+	public void removePlatforms(Collection<DatabasePlatform> pforms) {
+		this.removeItemsFromCollection(pforms, this.platforms, PLATFORMS_COLLECTION);
+		// the repository itself is not "dirty", but its branch is
+		this.markBranchDirty();
+		this.resetDefaultPlatform();
+	}
+
+	public void removePlatforms(Iterator<DatabasePlatform> pforms) {
+		this.removeItemsFromCollection(pforms, this.platforms, PLATFORMS_COLLECTION);
+		// the repository itself is not "dirty", but its branch is
+		this.markBranchDirty();
+		this.resetDefaultPlatform();
+	}
+
+
+	/**
+	 * this will only be null when we have no platforms
+	 */
+	public DatabasePlatform getDefaultPlatform() {
+		return this.defaultPlatform;
+	}
+
+	/**
+	 * the default cannot be set to null unless we have no
+	 * platforms
+	 */
+	public void setDefaultPlatform(DatabasePlatform defaultPlatform) {
+		if ((defaultPlatform == null) && (this.platforms.size() > 0)) {
+			throw new NullPointerException();
+		}
+		Object old = this.defaultPlatform;
+		this.defaultPlatform = defaultPlatform;
+		this.firePropertyChanged(DEFAULT_PLATFORM_PROPERTY, old, defaultPlatform);
+	}
+
+
+	public JDBCTypeRepository getJDBCTypeRepository() {
+		return this.jdbcTypeRepository;
+	}
+
+
+	// ********** queries **********
+
+	private File platformsDirectory() {
+		return new File(this.file.getParentFile(), PLATFORMS_DIRECTORY_NAME);
+	}
+
+	public DatabasePlatform platformNamed(String databasePlatformName) {
+		synchronized (this.platforms) {
+			for (DatabasePlatform platform : this.platforms) {
+				if (platform.getName().equals(databasePlatformName)) {
+					return platform;
+				}
+			}
+			throw new IllegalArgumentException("missing database platform named: " + databasePlatformName);
+		}
+	}
+
+	public DatabasePlatform platformForRuntimePlatformClassNamed(String runtimePlatformClassName) {
+		synchronized (this.platforms) {
+			for (DatabasePlatform platform : this.platforms) {
+				if (platform.getRuntimePlatformClassName().equals(runtimePlatformClassName)) {
+					return platform;
+				}
+			}
+			throw new IllegalArgumentException("missing database platform for run-time platform class: " + runtimePlatformClassName);
+		}
+	}
+
+	private Iterator<String> platformNames() {
+		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+			@Override
+			protected String transform(DatabasePlatform next) {
+				return next.getName();
+			}
+		};
+	}
+
+	private Iterator<String> platformShortFileNames() {
+		return new TransformationIterator<String, DatabasePlatform>(this.platforms()) {
+			@Override
+			protected String transform(DatabasePlatform next) {
+				return next.getShortFileName();
+			}
+		};
+	}
+
+	private Iterator<String> lowerCasePlatformShortFileNames() {
+		return new TransformationIterator<String, String>(this.platformShortFileNames()) {
+			@Override
+			protected String transform(String next) {
+				return next.toLowerCase();
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	@Override
+	protected void addChildrenTo(List<org.eclipse.persistence.tools.utility.node.Node> children) {
+		super.addChildrenTo(children);
+		synchronized (this.platforms) { children.addAll(this.platforms); }
+		children.add(this.jdbcTypeRepository);
+	}
+
+	@Override
+	protected void addTransientAspectNamesTo(Set<String> transientAspectNames) {
+		super.addTransientAspectNamesTo(transientAspectNames);
+		transientAspectNames.add(PLATFORMS_COLLECTION);
+	}
+
+	/**
+	 * check whether the default platform is still in the repository;
+	 * if it's not, fix it
+	 */
+	private void resetDefaultPlatform() {
+		synchronized (this.platforms) {
+			if ( ! this.platforms.contains(this.defaultPlatform)) {
+				if (this.platforms.isEmpty()) {
+					this.setDefaultPlatform(null);
+				} else {
+					this.setDefaultPlatform(this.platforms.iterator().next());
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns a clone of the specified platform;
+	 * the clone will be identical to the original, except its
+	 * name and file name will be slightly different
+	 */
+	@SuppressWarnings("null")
+	public DatabasePlatform clone(DatabasePlatform original) {
+		String originalName = original.getName();
+		String originalFileName = original.getShortFileName();
+		String originalFileNameBase = FileTools.stripExtension(originalFileName);
+		String originalFileNameExtension = FileTools.extension(originalFileName);
+
+		DatabasePlatform clone = null;
+		int cloneCount = 1;
+		boolean success = false;
+		while ( ! success) {
+			cloneCount++;
+			String cloneName = originalName + cloneCount;
+			String cloneFileName = originalFileNameBase + cloneCount + originalFileNameExtension;
+			try {
+				clone = this.addPlatform(cloneName, cloneFileName);
+				success = true;
+			} catch (IllegalArgumentException ex) {
+				String msg = ex.getMessage();
+				if ((msg.indexOf(cloneName) != -1) || (msg.indexOf(cloneFileName) != -1)) {
+					continue;	// try again
+				}
+				throw ex;	// must be some other problem...
+			}
+		}
+		clone.cloneFrom(original);
+		return clone;
+	}
+
+	/**
+	 * tell all the platforms a JDBC type has been added to the
+	 * JDBC type repository, so they need to synchronize
+	 */
+	void jdbcTypeAdded(JDBCType addedJDBCType) {
+		synchronized (this.platforms) {
+			for (DatabasePlatform platform : this.platforms) {
+				platform.jdbcTypeAdded(addedJDBCType);
+			}
+		}
+	}
+
+	/**
+	 * disallow duplicate platform names and files within a single repository
+	 */
+	private void checkPlatform(DatabasePlatform platform) {
+		this.checkPlatform(platform.getName(), platform.getShortFileName());
+	}
+
+	private void checkPlatform(String platformName, String platformShortFileName) {
+		this.checkPlatformName(platformName);
+		this.checkPlatformShortFileName(platformShortFileName);
+	}
+
+	/**
+	 * check whether a platform with the same name already exists;
+	 * if it does, throw an IllegalArgumentException
+	 */
+	void checkPlatformName(String platformName) {
+		if ((platformName == null) || (platformName.length() == 0)) {
+			throw new IllegalArgumentException("platform name is required");
+		}
+		if (CollectionTools.contains(this.platformNames(), platformName)) {
+			throw new IllegalArgumentException("duplicate platform name: " + platformName);
+		}
+	}
+
+	/**
+	 * check whether a platform with the same file name already exists;
+	 * if it does, throw an IllegalArgumentException;
+	 * ignore case since Windows file names are case-insensitive - meaning
+	 * we cannot have two files whose names differ only by their case
+	 */
+	void checkPlatformShortFileName(String platformShortFileName) {
+		if ((platformShortFileName == null) || (platformShortFileName.length() == 0)) {
+			throw new IllegalArgumentException("platform short file name is required");
+		}
+		if (FileTools.fileNameIsInvalid(platformShortFileName)) {
+			throw new IllegalArgumentException("invalid file name: " + platformShortFileName);
+		}
+		if (CollectionTools.contains(this.lowerCasePlatformShortFileNames(), platformShortFileName.toLowerCase())) {
+			throw new IllegalArgumentException("duplicate file name: " + platformShortFileName);
+		}
+	}
+
+
+	// ********** i/o **********
+
+	// ***** read
+	private void read() throws CorruptXMLException {
+		Document document = XMLTools.parse(this.file);
+		Node root = XMLTools.child(document, "platforms");
+		if (root == null) {
+			throw this.buildCorruptXMLException("missing root node: platforms");
+		}
+
+		this.name = XMLTools.childTextContent(root, "name", null);
+		if ((this.name == null) || (this.name.length() == 0)) {
+			throw this.buildCorruptXMLException("name is required");
+		}
+
+		// read up the JDBC repository first, since the JDBC types are referenced elsewhere
+		this.jdbcTypeRepository = new JDBCTypeRepository(this, XMLTools.child(root, "jdbc-type-repository"));
+
+		this.readPlatforms();
+
+		String defaultPlatformName = XMLTools.childTextContent(root, "default-platform", null);
+		if ((defaultPlatformName == null) || (defaultPlatformName.length() == 0)) {
+			if (this.platforms.size() == 0) {
+				// no problem
+			} else {
+				throw this.buildCorruptXMLException("default platform name is required");
+			}
+		} else {
+			if (this.platforms.size() == 0) {
+				throw this.buildCorruptXMLException("default platform should not be specified when there are no platforms");
+			}
+			try {
+				this.defaultPlatform = this.platformNamed(defaultPlatformName);
+			} catch (IllegalArgumentException ex) {
+				throw this.buildCorruptXMLException(ex);
+			}
+		}
+
+		// now save all the platform file names for later
+		this.originalPlatformShortFileNames = CollectionTools.collection(this.platformShortFileNames());
+
+		this.markEntireBranchClean();
+	}
+
+	/**
+	 * read in all the platform files
+	 */
+	private void readPlatforms() throws CorruptXMLException {
+		File platformsDirectory = this.platformsDirectory();
+		if (platformsDirectory.exists() && platformsDirectory.isDirectory()) {
+			File[] platformFiles = platformsDirectory.listFiles();
+			for (int i = platformFiles.length; i-- > 0; ) {
+				this.readPlatform(platformFiles[i]);
+			}
+		}
+	}
+
+	/**
+	 * read only files with an extension of .xml
+	 */
+	private void readPlatform(File platformFile) throws CorruptXMLException {
+		if (platformFile.isFile() && FileTools.extension(platformFile).toLowerCase().equals(".xml")) {
+			DatabasePlatform platform = new DatabasePlatform(this, platformFile);
+			try {
+				this.checkPlatform(platform);	// check for duplicates
+			} catch (IllegalArgumentException ex) {
+				throw this.buildCorruptXMLException(ex);
+			}
+			this.platforms.add(platform);
+		}
+	}
+
+	/**
+	 * tack the repository file on to the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(String message) {
+		return new CorruptXMLException(message + " (" + this.file.getPath() + ")");
+	}
+
+	/**
+	 * tack the repository file on to the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(Throwable t) {
+		return new CorruptXMLException(this.file.getPath(), t);
+	}
+
+	// ***** write
+	public void write() {
+		if (this.isCleanBranch()) {
+			return;
+		}
+		if (this.file == null) {
+			throw new IllegalStateException("the repository's file must be set before it is written");
+		}
+		// write the platforms first, that might be all we need to write out
+		this.writePlatforms();
+
+		// if, after writing out all the platforms, the repository is still dirty,
+		// we need to write out the repository itself
+		if (this.isDirtyBranch()) {
+			this.writeRepositoryFile();
+			this.markEntireBranchClean();
+		}
+	}
+
+	private void writePlatforms() {
+		File platformsDirectory = this.platformsDirectory();
+		if (platformsDirectory.exists()) {
+			if ( ! platformsDirectory.isDirectory()) {
+				throw new IllegalStateException("platforms directory is not a directory: " + platformsDirectory.getAbsolutePath());
+			}
+		} else {
+			if ( ! platformsDirectory.mkdirs()) {
+				throw new RuntimeException("unable to create platforms directory: " + platformsDirectory.getAbsolutePath());
+			}
+		}
+		this.deleteOldPlatformFiles(platformsDirectory);
+		synchronized (this.platforms) {
+			for (DatabasePlatform platform : this.platforms) {
+				platform.write(platformsDirectory);
+			}
+		}
+	}
+
+	/**
+	 * delete the platform files that were read in
+	 * earlier but are no longer needed
+	 */
+	private void deleteOldPlatformFiles(File platformsDirectory) {
+		// build the list of files to be deleted
+		Collection<String> deletedPlatformFileNames = new HashBag<String>(this.originalPlatformShortFileNames);
+		Collection<String> currentPlatformFileNames = CollectionTools.collection(this.platformShortFileNames());
+		deletedPlatformFileNames.removeAll(currentPlatformFileNames);
+
+		// now delete them
+		for (String fileName : deletedPlatformFileNames) {
+			new File(platformsDirectory, fileName).delete();
+		}
+
+		// reset the file names for the next write
+		this.originalPlatformShortFileNames = currentPlatformFileNames;
+	}
+
+	private void writeRepositoryFile() {
+		Document document = XMLTools.newDocument();
+		Node root = document.createElement("platforms");
+		document.appendChild(root);
+		XMLTools.addSimpleTextNode(root, "name", this.name);
+
+		// the default platform can be null when there are no platforms
+		if (this.defaultPlatform != null) {
+			XMLTools.addSimpleTextNode(root, "default-platform", this.defaultPlatform.getName());
+		}
+
+		this.jdbcTypeRepository.write(root.appendChild(document.createElement("jdbc-type-repository")));
+
+		XMLTools.print(document, this.file);
+
+		if (this.originalFile != null) {
+			// the "original file" is only set when the repos file is renamed but not moved
+			if ( ! this.originalFile.delete()) {
+				throw new RuntimeException("unable to delete original file: " + this.originalFile.getPath());
+			}
+			this.originalFile = null;
+		}
+	}
+
+
+	// ********** printing and displaying **********
+
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+	public void toString(StringBuffer sb) {
+		for (Iterator<DatabasePlatform> stream = this.platforms(); stream.hasNext(); ) {
+			DatabasePlatform platform = stream.next();
+			platform.toString(sb);
+			if (stream.hasNext()) {
+				sb.append(", ");
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java
new file mode 100644
index 0000000..3e1eb17
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/DatabaseType.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import java.util.Iterator;
+
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Node;
+
+/**
+ * A database type holds all the settings for a platform-specific database type.
+ * For example, the Oracle database type VARCHAR2
+ * 	- maps to the JDBC type VARCHAR
+ * 	- allows and requires a size specification
+ * 	- has a initial size of 20 when generating tables
+ * 	- does not allow a sub-size specification
+ * 	- allows a null value
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class DatabaseType extends AbstractNode {
+
+	/**
+	 * a name uniquely identifying the type within a
+	 * database platform
+	 */
+	private String name;
+		public static final String NAME_PROPERTY = "name";
+
+	/**
+	 * the JDBC type most closely resembling the
+	 * platform-specific database type
+	 */
+	private JDBCType jdbcType;
+		public static final String JDBC_TYPE_PROPERTY = "jdbcType";
+
+	/**
+	 * whether the type can be declared with a size
+	 */
+	private boolean allowsSize;
+		public static final String ALLOWS_SIZE_PROPERTY = "allowsSize";
+
+	/**
+	 * whether the type *requires* a size...
+	 */
+	private boolean requiresSize;
+		public static final String REQUIRES_SIZE_PROPERTY = "requiresSize";
+
+	/**
+	 * ...and, if it does, what the initial size should be
+	 */
+	private int initialSize;
+		public static final String INITIAL_SIZE_PROPERTY = "initialSize";
+
+	/**
+	 * whether the type can be declared with a "sub-size";
+	 * this is typically a numeric scale
+	 */
+	private boolean allowsSubSize;
+		public static final String ALLOWS_SUB_SIZE_PROPERTY = "allowsSubSize";
+
+	/**
+	 * whether the type allows NULL values
+	 */
+	private boolean allowsNull;
+		public static final String ALLOWS_NULL_PROPERTY = "allowsNull";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the type is read from an XML file
+	 */
+	DatabaseType(DatabasePlatform platform, Node node) throws CorruptXMLException {
+		super(platform);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new type (which shouldn't happen very often,
+	 * since all the typical platforms have already been built...)
+	 */
+	DatabaseType(DatabasePlatform platform, String name) {
+		super(platform);
+		this.name = name;
+		this.jdbcType = this.jdbcTypeRepository().getDefaultJDBCType();
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.mappingsmodel.AbstractNodeModel#initialize()
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.allowsSize = true;
+		this.requiresSize = false;
+		this.initialSize = 0;
+		this.allowsSubSize = false;
+		this.allowsNull = true;
+	}
+
+
+	// ********** accessors **********
+
+	public DatabasePlatform getPlatform() {
+		return  (DatabasePlatform) this.getParent();
+	}
+
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.getPlatform().checkDatabaseTypeName(name);
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+
+	public JDBCType getJDBCType() {
+		return this.jdbcType;
+	}
+
+	public void setJDBCType(JDBCType jdbcType) {
+		if (jdbcType == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.jdbcType;
+		this.jdbcType = jdbcType;
+		this.firePropertyChanged(JDBC_TYPE_PROPERTY, old, jdbcType);
+	}
+
+
+	public boolean allowsSize() {
+		return this.allowsSize;
+	}
+
+	public void setAllowsSize(boolean allowsSize) {
+		boolean old = this.allowsSize;
+		this.allowsSize = allowsSize;
+		this.firePropertyChanged(ALLOWS_SIZE_PROPERTY, old, allowsSize);
+
+		// if size is not allowed, sub-size is not either and size cannot be required
+		if ( ! allowsSize) {
+			this.setAllowsSubSize(false);
+			this.setRequiresSize(false);
+		}
+	}
+
+
+	public boolean requiresSize() {
+		return this.requiresSize;
+	}
+
+	public void setRequiresSize(boolean requiresSize) {
+		boolean old = this.requiresSize;
+		this.requiresSize = requiresSize;
+		this.firePropertyChanged(REQUIRES_SIZE_PROPERTY, old, requiresSize);
+
+		// if size is required, size must be allowed...
+		if (requiresSize) {
+			this.setAllowsSize(true);
+		} else {
+			this.setInitialSize(0);
+		}
+	}
+
+
+	public int getInitialSize() {
+		return this.initialSize;
+	}
+
+	public void setInitialSize(int initialSize) {
+		if (initialSize < 0) {
+			throw new IllegalArgumentException("initial size must be greater than or equal to zero" + initialSize);
+		}
+		int old = this.initialSize;
+		this.initialSize = initialSize;
+		this.firePropertyChanged(INITIAL_SIZE_PROPERTY, old, initialSize);
+
+		// if there is a initial size, it must be required
+		if (initialSize != 0) {
+			this.setRequiresSize(true);
+		}
+	}
+
+
+	public boolean allowsSubSize() {
+		return this.allowsSubSize;
+	}
+
+	public void setAllowsSubSize(boolean allowsSubSize) {
+		boolean old = this.allowsSubSize;
+		this.allowsSubSize = allowsSubSize;
+		this.firePropertyChanged(ALLOWS_SUB_SIZE_PROPERTY, old, allowsSubSize);
+
+		// if sub-size is allowed, size must be also
+		if (allowsSubSize) {
+			this.setAllowsSize(true);
+		}
+	}
+
+
+	public boolean allowsNull() {
+		return this.allowsNull;
+	}
+
+	public void setAllowsNull(boolean allowsNull) {
+		boolean old = this.allowsNull;
+		this.allowsNull = allowsNull;
+		this.firePropertyChanged(ALLOWS_NULL_PROPERTY, old, allowsNull);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Returns a Java type declaration that can used for this database type;
+	 * this is used for generating classes from tables
+	 */
+	public JavaTypeDeclaration javaTypeDeclaration() {
+		return this.jdbcTypeRepository().javaTypeDeclarationFor(this.getJDBCType());
+	}
+
+	private DatabasePlatformRepository platformRepository() {
+		return this.getPlatform().getRepository();
+	}
+
+	private JDBCTypeRepository jdbcTypeRepository() {
+		return this.platformRepository().getJDBCTypeRepository();
+	}
+
+	private JDBCType jdbcTypeNamed(String jdbcTypeName) {
+		return this.jdbcTypeRepository().jdbcTypeNamed(jdbcTypeName);
+	}
+
+	/**
+	 * Returns all the JDBC types that the database type
+	 * could be mapped to. Simplifies UI code....
+	 */
+	public Iterator<JDBCType> jdbcTypes() {
+		return this.jdbcTypeRepository().jdbcTypes();
+	}
+
+	/**
+	 * Returns the size of all the JDBC types that the database type
+	 * could be mapped to. Simplifies UI code....
+	 */
+	public int jdbcTypesSize() {
+		return this.jdbcTypeRepository().jdbcTypesSize();
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * copy all the settings from the original type
+	 * to this, newly-created, type
+	 */
+	void cloneFrom(DatabaseType originalType) {
+		// the name has been set by the time we get here
+		this.setJDBCType(originalType.getJDBCType());	// the JDBC type should NOT be cloned
+		this.setAllowsSize(originalType.allowsSize());
+		this.setRequiresSize(originalType.requiresSize());
+		this.setInitialSize(originalType.getInitialSize());
+		this.setAllowsSubSize(originalType.allowsSubSize());
+		this.setAllowsNull(originalType.allowsNull());
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		if (node == null) {
+			throw this.buildCorruptXMLException("missing node");
+		}
+		this.name = XMLTools.childTextContent(node, "name", null);
+		if ((this.name == null) || (this.name.length() == 0)) {
+			throw this.buildCorruptXMLException("name is required");
+		}
+
+		String jdbcTypeName = XMLTools.childTextContent(node, "jdbc-type", null);
+		try {
+			this.jdbcType = this.jdbcTypeNamed(jdbcTypeName);
+		} catch (IllegalArgumentException ex) {
+			throw this.buildCorruptXMLException(ex);
+		}
+
+		this.allowsSize = XMLTools.childBooleanContent(node, "allows-size", false);
+
+		this.requiresSize = XMLTools.childBooleanContent(node, "requires-size", false);
+		if (( ! this.allowsSize) && this.requiresSize) {
+			throw this.buildCorruptXMLException("size cannot be required when it is not allowed");
+		}
+
+		this.initialSize = XMLTools.childIntContent(node, "initial-size", 0);
+		if (( ! this.requiresSize) && (this.initialSize != 0)) {
+			throw this.buildCorruptXMLException("initial size cannot be specified when size is not required");
+		}
+
+		this.allowsSubSize = XMLTools.childBooleanContent(node, "allows-sub-size", false);
+		if (( ! this.allowsSize) && this.allowsSubSize) {
+			throw this.buildCorruptXMLException("sub-size cannot be allowed when size is not allowed");
+		}
+
+		this.allowsNull = XMLTools.childBooleanContent(node, "allows-null", false);
+	}
+
+	/**
+	 * tack on some more information on the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(String message) {
+		return new CorruptXMLException(message + " (" + this.corruptXMLLocation() + ")");
+	}
+
+	/**
+	 * tack on some more information on the message
+	 */
+	private CorruptXMLException buildCorruptXMLException(Throwable t) {
+		return new CorruptXMLException(this.corruptXMLLocation(), t);
+	}
+
+	private String corruptXMLLocation() {
+		return this.getPlatform().getName() + ":" + this.name;
+	}
+
+	void write(Node node) {
+		XMLTools.addSimpleTextNode(node, "name", this.name);
+		XMLTools.addSimpleTextNode(node, "jdbc-type", this.jdbcType.getName());
+		XMLTools.addSimpleTextNode(node, "allows-size", this.allowsSize, false);
+		XMLTools.addSimpleTextNode(node, "requires-size", this.requiresSize, false);
+		XMLTools.addSimpleTextNode(node, "initial-size", this.initialSize, 0);
+		XMLTools.addSimpleTextNode(node, "allows-sub-size", this.allowsSubSize, false);
+		XMLTools.addSimpleTextNode(node, "allows-null", this.allowsNull, false);
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		sb.append(this.name);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java
new file mode 100644
index 0000000..94350b8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCType.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Node;
+
+/**
+ * Associate the Java constant and the JDBC type name. These are typically derived from java.sql.Types.
+ *
+ * @see java.sql.Types
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JDBCType extends AbstractNode {
+
+	/**
+	 * A name uniquely identifying the type within a JDBC type repository
+	 */
+	private String name;
+		public static final String NAME_PROPERTY = "name";
+
+	/**
+	 * The JDBC code used by JDBC drivers
+	 */
+	private int code;
+		public static final String CODE_PROPERTY = "code";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the type is read from an XML file
+	 */
+	JDBCType(JDBCTypeRepository repository, Node node) throws CorruptXMLException {
+		super(repository);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new type (which shouldn't happen very often,
+	 * since all the typical types have already been built...)
+	 */
+	JDBCType(JDBCTypeRepository repository, String name, int code) {
+		super(repository);
+		this.name = name;
+		this.code = code;
+	}
+
+
+	// ********** accessors **********
+
+	private JDBCTypeRepository getJDBCTypeRepository() {
+		return  (JDBCTypeRepository) this.getParent();
+	}
+
+
+	/**
+	 * Returns the name of the type, as defined in java.sql.Types.
+	 */
+	public String getName() {
+		return this.name;
+	}
+
+	/**
+	 * Set the name of the type, as defined in java.sql.Types.
+	 * No duplicates allowed.
+	 */
+	public void setName(String name) {
+		this.getJDBCTypeRepository().checkJDBCTypeName(name);
+		Object old = this.name;
+		this.name = name;
+		this.firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+
+
+	/**
+	 * Returns the type code, as defined in java.sql.Types.
+	 */
+	public int getCode() {
+		return this.code;
+	}
+
+	/**
+	 * Set the type code, as defined in java.sql.Types.
+	 * No duplicates allowed.
+	 */
+	public void setCode(int code) {
+		this.getJDBCTypeRepository().checkJDBCTypeCode(code);
+		int old = this.code;
+		this.code = code;
+		this.firePropertyChanged(CODE_PROPERTY, old, code);
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		if (node == null) {
+			throw new CorruptXMLException("missing node");
+		}
+		this.name = XMLTools.childTextContent(node, "name", null);
+		if ((this.name == null) || (this.name.length() == 0)) {
+			throw new CorruptXMLException("name is required");
+		}
+		// we just picked a random, improbable code for the default
+		this.code = XMLTools.childIntContent(node, "code", -7777);
+	}
+
+	void write(Node node) {
+		XMLTools.addSimpleTextNode(node, "name", this.name);
+		// we just picked a random, improbable code for the default
+		XMLTools.addSimpleTextNode(node, "code", this.code, -7777);
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		return this.name;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		sb.append(this.name);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java
new file mode 100644
index 0000000..bdc2c36
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeRepository.java
@@ -0,0 +1,803 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import java.lang.reflect.Field;
+import java.sql.Types;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.iterators.CloneIterator;
+import org.eclipse.persistence.tools.utility.iterators.TransformationIterator;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * This repository holds the JDBC Types that correspond to the data types
+ * defined in java.sql.Types. It also holds the mappings between JDBC
+ * types and Java type declarations, which are stored in an XML file.
+ *
+ * @see java.sql.Types
+ *
+ * For information on mapping JDBC and Java types,
+ * see "Getting Started with JDBC API"
+ * 	http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JDBCTypeRepository extends AbstractNode {
+
+	/**
+	 * All the data type constants in java.sql.Types (e.g. INTEGER: 4);
+	 * by default, these are calculated via reflection on java.sql.Types.
+	 * This will always contain at least one type, so we always have a default.
+	 * @see java.sql.Types
+	 */
+	private Collection<JDBCType> jdbcTypes;
+		public static final String JDBC_TYPES_COLLECTION = "jdbcTypes";
+
+	// these aren't really JDBC types, although they are defined in java.sql.Types
+	private static final int[] DEFAULT_UNUSED_JDBC_TYPE_CODES = {Types.NULL};
+
+	/**
+	 * The default JDBC type used to determine the default database type
+	 * used when generating tables.
+	 */
+	private JDBCType defaultJDBCType;
+		public static final String DEFAULT_JDBC_TYPE_PROPERTY = "defaultJDBCType";
+
+	private static final int DEFAULT_DEFAULT_JDBC_TYPE_CODE = Types.VARCHAR;
+
+	/**
+	 * Mappings of the JDBC types to Java type declarations
+	 * (e.g. java.sql.Types.INTEGER maps to int).
+	 * These are used to generate classes from tables.
+	 * This collection is kept in synch with the jdbcTypes collection.
+	 */
+	private Collection<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings;
+		public static final String JDBC_TYPE_TO_JAVA_TYPE_DECLARATION_MAPPINGS_COLLECTION = "jdbcTypeToJavaTypeDeclarationMappings";
+
+	/**
+	 * Mappings of typical Java type declarations to the JDBC types
+	 * (e.g. int and java.lang.Integer map to java.sql.Types.INTEGER).
+	 * These are used to generate tables from classes.
+	 */
+	private Collection<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings;
+		public static final String JAVA_TYPE_DECLARATION_TO_JDBC_TYPE_MAPPINGS_COLLECTION = "javaTypeDeclarationToJDBCTypeMappings";
+
+	private static final boolean JDK16 = jdkIsVersion("1.6");
+
+	private static boolean jdkIsVersion(String version) {
+		return System.getProperty("java.version").indexOf(version) != -1;
+	}
+
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the repository is read from an XML file
+	 */
+	JDBCTypeRepository(DatabasePlatformRepository platformRepository, Node node) throws CorruptXMLException {
+		super(platformRepository);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new repository (which shouldn't happen very often...)
+	 */
+	JDBCTypeRepository(DatabasePlatformRepository platformRepository) {
+		super(platformRepository);
+		this.initializeDefaults();
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.mappingsmodel.AbstractNodeModel#initialize()
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.jdbcTypes = new Vector<JDBCType>();
+		this.jdbcTypeToJavaTypeDeclarationMappings = new Vector<JDBCTypeToJavaTypeDeclarationMapping>();
+		this.javaTypeDeclarationToJDBCTypeMappings = new Vector<JavaTypeDeclarationToJDBCTypeMapping>();
+	}
+
+	/**
+	 * Initialize our attributes to some reasonable defaults.
+	 */
+	private void initializeDefaults() {
+		this.initializeDefaultJDBCTypes();
+		this.defaultJDBCType = this.jdbcTypeForCode(DEFAULT_DEFAULT_JDBC_TYPE_CODE);
+
+		this.initializeDefaultJDBCToJavaMappings();
+		// TODO change this conditional to
+		//     if (JDK16) {
+		// and uncomment Types in #initializeDefaultJDBCToJavaMappings()
+		// when we start compiling with jdk1.6
+		if ( ! JDK16) {
+			this.checkJDBCTypeToJavaTypeDeclarationMappings();
+		}
+
+		this.initializeDefaultJavaToJDBCMappings();
+	}
+
+	private void checkJDBCTypeToJavaTypeDeclarationMappings() {
+		// make sure we have mapped ALL the JDBC types
+		if (this.jdbcTypeToJavaTypeDeclarationMappings.size() != this.jdbcTypes.size()) {
+			throw new IllegalStateException("the JDBC type mappings were not initialized properly");
+		}
+	}
+
+	/**
+	 * build up the default JDBC types via reflection
+	 * @see java.sql.Types
+	 */
+	private void initializeDefaultJDBCTypes() {
+		Field[] fields = Types.class.getDeclaredFields();
+		for (int i = fields.length; i-- > 0; ) {
+			String name = fields[i].getName();
+			int code;
+			try {
+				code = ((Integer) fields[i].get(null)).intValue();
+			} catch (IllegalAccessException ex) {
+				throw new RuntimeException(ex);	// shouldn't happen...
+			}
+			if ( ! CollectionTools.contains(CollectionTools.list(DEFAULT_UNUSED_JDBC_TYPE_CODES), code)) {
+				this.checkJDBCType(name, code);	// check for duplicates
+				this.jdbcTypes.add(new JDBCType(this, name, code));
+			}
+		}
+	}
+
+	/**
+	 * hard code the default mappings from the JDBC types to the
+	 * appropriate Java type declarations
+	 * @see java.sql.Types
+	 * see "Getting Started with the JDBC API"
+	 * http://java.sun.com/javase/6/docs/technotes/guides/jdbc/getstart/GettingStartedTOC.fm.html
+	 *     or
+	 * 	http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html
+	 */
+	// TODO uncomment 6 new Types when we start compiling with jdk1.6
+	private void initializeDefaultJDBCToJavaMappings() {
+		this.addJDBCToJavaMapping(Types.ARRAY,				java.sql.Array.class);
+		this.addJDBCToJavaMapping(Types.BIGINT,				long.class);
+		this.addJDBCToJavaMapping(Types.BINARY,				byte.class, 1);	// byte[]
+		this.addJDBCToJavaMapping(Types.BIT,					boolean.class);
+		this.addJDBCToJavaMapping(Types.BLOB,				java.sql.Blob.class);
+		this.addJDBCToJavaMapping(Types.BOOLEAN,			boolean.class);
+		this.addJDBCToJavaMapping(Types.CHAR,				java.lang.String.class);
+		this.addJDBCToJavaMapping(Types.CLOB,				java.sql.Clob.class);
+		this.addJDBCToJavaMapping(Types.DATALINK,			java.net.URL.class);
+		this.addJDBCToJavaMapping(Types.DATE,				java.sql.Date.class);
+		this.addJDBCToJavaMapping(Types.DECIMAL,			java.math.BigDecimal.class);
+		this.addJDBCToJavaMapping(Types.DISTINCT,			java.lang.Object.class);
+		this.addJDBCToJavaMapping(Types.DOUBLE,			double.class);
+		this.addJDBCToJavaMapping(Types.FLOAT,				double.class);
+		this.addJDBCToJavaMapping(Types.INTEGER,			int.class);
+		this.addJDBCToJavaMapping(Types.JAVA_OBJECT,	java.lang.Object.class);
+//		this.addJDBCToJavaMapping(Types.LONGNVARCHAR,					java.lang.String.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.LONGVARBINARY,	byte.class, 1);	// byte[]
+		this.addJDBCToJavaMapping(Types.LONGVARCHAR,	java.lang.String.class);
+//		this.addJDBCToJavaMapping(Types.NCHAR,					java.lang.String.class); // JDK1.6
+//		this.addJDBCToJavaMapping(Types.NCLOB,					java.sql.NClob.class); // JDK1.6
+//		this.addJDBCToJavaMapping(Types.NVARCHAR,					java.lang.String.class); // JDK1.6
+		// not sure why this is defined in java.sql.Types
+//		this.addJDBCToJavaMapping(Types.NULL,					java.lang.Object.class);
+		this.addJDBCToJavaMapping(Types.NUMERIC,			java.math.BigDecimal.class);
+		this.addJDBCToJavaMapping(Types.OTHER,				java.lang.Object.class);	// ???
+		this.addJDBCToJavaMapping(Types.REAL,				float.class);
+		this.addJDBCToJavaMapping(Types.REF,					java.sql.Ref.class);
+//		this.addJDBCToJavaMapping(Types.ROWID,					java.sql.RowId.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.SMALLINT,			short.class);
+//		this.addJDBCToJavaMapping(Types.SQLXML,					java.sql.SQLXML.class); // JDK1.6
+		this.addJDBCToJavaMapping(Types.STRUCT,			java.sql.Struct.class);
+		this.addJDBCToJavaMapping(Types.TIME,				java.sql.Time.class);
+		this.addJDBCToJavaMapping(Types.TIMESTAMP,		java.sql.Timestamp.class);
+		this.addJDBCToJavaMapping(Types.TINYINT,			byte.class);
+		this.addJDBCToJavaMapping(Types.VARBINARY,		byte.class, 1);	// byte[]
+		this.addJDBCToJavaMapping(Types.VARCHAR,			java.lang.String.class);
+	}
+
+	private void addJDBCToJavaMapping(int jdbcTypeCode, Class<?> javaClass) {
+		this.addJDBCToJavaMapping(jdbcTypeCode, javaClass, 0);
+	}
+
+	private void addJDBCToJavaMapping(int jdbcTypeCode, Class<?> javaClass, int arrayDepth) {
+		JDBCType jdbcType = this.jdbcTypeForCode(jdbcTypeCode);
+		this.checkJDBCToJavaMapping(jdbcType);	// check for duplicates
+		this.jdbcTypeToJavaTypeDeclarationMappings.add(new JDBCTypeToJavaTypeDeclarationMapping(this, jdbcType, javaClass.getName(), arrayDepth));
+	}
+
+	/**
+	 * hard code the default mappings from the typical Java type declarations to the
+	 * appropriate JDBC types
+	 * @see java.sql.Types
+	 * see "Getting Started with JDBC API"
+	 * 	http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html
+	 */
+	private void initializeDefaultJavaToJDBCMappings() {
+		this.addJavaToJDBCMapping(java.lang.String.class,			Types.VARCHAR);
+
+		this.addJavaToJDBCMapping(boolean.class,					Types.BOOLEAN);
+		this.addJavaToJDBCMapping(java.lang.Boolean.class,		Types.BOOLEAN);
+
+		this.addJavaToJDBCMapping(char.class,							Types.CHAR);
+		this.addJavaToJDBCMapping(java.lang.Character.class,		Types.CHAR);
+
+		this.addJavaToJDBCMapping(byte.class,							Types.TINYINT);
+		this.addJavaToJDBCMapping(java.lang.Byte.class,			Types.TINYINT);
+
+		this.addJavaToJDBCMapping(short.class,						Types.SMALLINT);
+		this.addJavaToJDBCMapping(java.lang.Short.class,			Types.SMALLINT);
+
+		this.addJavaToJDBCMapping(int.class,							Types.INTEGER);
+		this.addJavaToJDBCMapping(java.lang.Integer.class,			Types.INTEGER);
+
+		this.addJavaToJDBCMapping(long.class,							Types.BIGINT);
+		this.addJavaToJDBCMapping(java.lang.Long.class,			Types.BIGINT);
+
+		this.addJavaToJDBCMapping(float.class,							Types.REAL);
+		this.addJavaToJDBCMapping(java.lang.Float.class,			Types.REAL);
+
+		this.addJavaToJDBCMapping(double.class,						Types.DOUBLE);
+		this.addJavaToJDBCMapping(java.lang.Double.class,			Types.DOUBLE);
+
+		this.addJavaToJDBCMapping(java.lang.Number.class,		Types.NUMERIC);
+		this.addJavaToJDBCMapping(java.math.BigDecimal.class,	Types.NUMERIC);
+		this.addJavaToJDBCMapping(java.math.BigInteger.class,	Types.NUMERIC);
+
+		this.addJavaToJDBCMapping(java.util.Date.class,				Types.DATE);
+		this.addJavaToJDBCMapping(java.sql.Date.class,				Types.DATE);
+		this.addJavaToJDBCMapping(java.sql.Time.class,				Types.TIME);
+		this.addJavaToJDBCMapping(java.sql.Timestamp.class,		Types.TIMESTAMP);
+		this.addJavaToJDBCMapping(java.util.Calendar.class,		Types.TIMESTAMP);
+
+		this.addJavaToJDBCMapping(java.sql.Blob.class,				Types.BLOB);
+		this.addJavaToJDBCMapping(java.sql.Clob.class,				Types.CLOB);
+
+		this.addJavaToJDBCMapping(java.sql.Array.class,				Types.ARRAY);
+		this.addJavaToJDBCMapping(java.sql.Struct.class,			Types.STRUCT);
+		this.addJavaToJDBCMapping(java.sql.Ref.class,				Types.REF);
+		this.addJavaToJDBCMapping(java.net.URL.class,				Types.DATALINK);
+
+		this.addJavaToJDBCMapping(byte.class, 1,						Types.VARBINARY);	// byte[]
+		this.addJavaToJDBCMapping(char.class, 1,						Types.VARCHAR);	// char[]
+
+		this.addJavaToJDBCMapping(java.lang.Class.class,			Types.VARCHAR);
+	}
+
+	private void addJavaToJDBCMapping(Class<?> javaClass, int jdbcTypeCode) {
+		this.addJavaToJDBCMapping(javaClass, 0, jdbcTypeCode);
+	}
+
+	private void addJavaToJDBCMapping(Class<?> javaClass, int arrayDepth, int jdbcTypeCode) {
+		String javaClassName = javaClass.getName();
+		this.checkJavaToJDBCMapping(javaClassName, arrayDepth);	// check for duplicates
+		this.javaTypeDeclarationToJDBCTypeMappings.add(new JavaTypeDeclarationToJDBCTypeMapping(this, javaClassName, arrayDepth, this.jdbcTypeForCode(jdbcTypeCode)));
+	}
+
+
+	// ********** accessors **********
+
+	private DatabasePlatformRepository getPlatformRepository() {
+		return  (DatabasePlatformRepository) this.getParent();
+	}
+
+
+	public Iterator<JDBCType> jdbcTypes() {
+		return new CloneIterator<JDBCType>(this.jdbcTypes) {
+			@Override
+			protected void remove(JDBCType current) {
+				JDBCTypeRepository.this.removeJDBCType(current);
+			}
+		};
+	}
+
+	public int jdbcTypesSize() {
+		return this.jdbcTypes.size();
+	}
+
+	public JDBCType addJDBCType(String name, int code) {
+		this.checkJDBCType(name, code);
+		return this.addJDBCType(new JDBCType(this, name, code));
+	}
+
+	private JDBCType addJDBCType(JDBCType jdbcType) {
+		this.addItemToCollection(jdbcType, this.jdbcTypes, JDBC_TYPES_COLLECTION);
+		this.jdbcTypeAdded(jdbcType);
+		return jdbcType;
+	}
+
+	private void jdbcTypeAdded(JDBCType addedJDBCType) {
+		// synchronize the mappings
+		this.addJDBCTypeToJavaTypeDeclarationMapping(addedJDBCType, java.lang.Object.class.getName(), 0);	// hmmm...
+		// add the new JDBC type to all the platforms' mappings
+		this.getPlatformRepository().jdbcTypeAdded(addedJDBCType);
+	}
+
+	public void removeJDBCType(JDBCType jdbcType) {
+		if (jdbcType == this.defaultJDBCType) {
+			throw new IllegalArgumentException("the default JDBC type may not be removed: " + jdbcType);
+		}
+		this.removeItemFromCollection(jdbcType, this.jdbcTypes, JDBC_TYPES_COLLECTION);
+		this.jdbcTypeRemoved(jdbcType);
+	}
+
+	private void jdbcTypeRemoved(JDBCType removedJDBCType) {
+		for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings(); stream.hasNext(); ) {
+			if (stream.next().getJDBCType() == removedJDBCType) {
+				stream.remove();
+				break;	// there should be only one...
+			}
+		}
+		for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings(); stream.hasNext(); ) {
+			JavaTypeDeclarationToJDBCTypeMapping mapping = stream.next();
+			if (mapping.getJDBCType() == removedJDBCType) {
+				mapping.setJDBCType(this.defaultJDBCType);		// hmmm...
+			}
+		}
+		this.getPlatformRepository().nodeRemoved(removedJDBCType);
+	}
+
+	public void removeJDBCTypes(Collection<JDBCType> types) {
+		if (types.contains(this.defaultJDBCType)) {
+			throw new IllegalArgumentException("the default JDBC type may not be removed: " + this.defaultJDBCType);
+		}
+		this.removeItemsFromCollection(types, this.jdbcTypes, JDBC_TYPES_COLLECTION);
+		this.jdbcTypesRemoved(types);
+	}
+
+	private void jdbcTypesRemoved(Collection<JDBCType> removedJDBCTypes) {
+		for (Iterator<JDBCType> stream = removedJDBCTypes.iterator(); stream.hasNext(); ) {
+			this.jdbcTypeRemoved(stream.next());
+		}
+	}
+
+	public void removeJDBCTypes(Iterator<JDBCType> types) {
+		this.removeJDBCTypes(CollectionTools.collection(types));
+	}
+
+
+	// default JDBC type
+	/**
+	 * this will only be null when we have no JDBC types
+	 */
+	public JDBCType getDefaultJDBCType() {
+		return this.defaultJDBCType;
+	}
+
+	/**
+	 * the default cannot be set to null
+	 */
+	public void setDefaultJDBCType(JDBCType defaultJDBCType) {
+		if (defaultJDBCType == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.defaultJDBCType;
+		this.defaultJDBCType = defaultJDBCType;
+		this.firePropertyChanged(DEFAULT_JDBC_TYPE_PROPERTY, old, defaultJDBCType);
+	}
+
+
+	// JDBC => Java mappings
+	public Iterator<JDBCTypeToJavaTypeDeclarationMapping> jdbcTypeToJavaTypeDeclarationMappings() {
+		return new CloneIterator<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings) {
+			@Override
+			protected void remove(JDBCTypeToJavaTypeDeclarationMapping current) {
+				JDBCTypeRepository.this.removeJDBCTypeToJavaTypeDeclarationMapping(current);
+			}
+		};
+	}
+
+	public int jdbcTypeToJavaTypeDeclarationMappingsSize() {
+		return this.jdbcTypeToJavaTypeDeclarationMappings.size();
+	}
+
+	public JDBCTypeToJavaTypeDeclarationMapping addJDBCTypeToJavaTypeDeclarationMapping(JDBCType jdbcType, String javaClassName, int arrayDepth) {
+		this.checkJDBCToJavaMapping(jdbcType);
+		return this.addJDBCTypeToJavaTypeDeclarationMapping(new JDBCTypeToJavaTypeDeclarationMapping(this, jdbcType, javaClassName, arrayDepth));
+	}
+
+	private JDBCTypeToJavaTypeDeclarationMapping addJDBCTypeToJavaTypeDeclarationMapping(JDBCTypeToJavaTypeDeclarationMapping mapping) {
+		this.addItemToCollection(mapping, this.jdbcTypeToJavaTypeDeclarationMappings, JDBC_TYPE_TO_JAVA_TYPE_DECLARATION_MAPPINGS_COLLECTION);
+		return mapping;
+	}
+
+	public void removeJDBCTypeToJavaTypeDeclarationMapping(JDBCTypeToJavaTypeDeclarationMapping mapping) {
+		this.removeItemFromCollection(mapping, this.jdbcTypeToJavaTypeDeclarationMappings, JDBC_TYPE_TO_JAVA_TYPE_DECLARATION_MAPPINGS_COLLECTION);
+	}
+
+	public void removeJDBCTypeToJavaTypeDeclarationMappings(Collection<JDBCTypeToJavaTypeDeclarationMapping> mappings) {
+		this.removeItemsFromCollection(mappings, this.jdbcTypeToJavaTypeDeclarationMappings, JDBC_TYPE_TO_JAVA_TYPE_DECLARATION_MAPPINGS_COLLECTION);
+	}
+
+	public void removeJDBCTypeToJavaTypeDeclarationMappings(Iterator<JDBCTypeToJavaTypeDeclarationMapping> mappings) {
+		this.removeItemsFromCollection(mappings, this.jdbcTypeToJavaTypeDeclarationMappings, JDBC_TYPE_TO_JAVA_TYPE_DECLARATION_MAPPINGS_COLLECTION);
+	}
+
+
+	// Java => JDBC mappings
+	public Iterator<JavaTypeDeclarationToJDBCTypeMapping> javaTypeDeclarationToJDBCTypeMappings() {
+		return new CloneIterator<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings) {
+			@Override
+			protected void remove(JavaTypeDeclarationToJDBCTypeMapping current) {
+				JDBCTypeRepository.this.removeJavaTypeDeclarationToJDBCTypeMapping(current);
+			}
+		};
+	}
+
+	public int javaTypeDeclarationToJDBCTypeMappingsSize() {
+		return this.javaTypeDeclarationToJDBCTypeMappings.size();
+	}
+
+	public JavaTypeDeclarationToJDBCTypeMapping addJavaTypeDeclarationToJDBCTypeMapping(String javaClassName, int arrayDepth, JDBCType jdbcType) {
+		this.checkJavaToJDBCMapping(javaClassName, arrayDepth);
+		return this.addJavaTypeDeclarationToJDBCTypeMapping(new JavaTypeDeclarationToJDBCTypeMapping(this, javaClassName, arrayDepth, jdbcType));
+	}
+
+	private JavaTypeDeclarationToJDBCTypeMapping addJavaTypeDeclarationToJDBCTypeMapping(JavaTypeDeclarationToJDBCTypeMapping mapping) {
+		this.addItemToCollection(mapping, this.javaTypeDeclarationToJDBCTypeMappings, JAVA_TYPE_DECLARATION_TO_JDBC_TYPE_MAPPINGS_COLLECTION);
+		return mapping;
+	}
+
+	public void removeJavaTypeDeclarationToJDBCTypeMapping(JavaTypeDeclarationToJDBCTypeMapping mapping) {
+		this.removeItemFromCollection(mapping, this.javaTypeDeclarationToJDBCTypeMappings, JAVA_TYPE_DECLARATION_TO_JDBC_TYPE_MAPPINGS_COLLECTION);
+	}
+
+	public void removeJavaTypeDeclarationToJDBCTypeMappings(Collection<JavaTypeDeclarationToJDBCTypeMapping> mappings) {
+		this.removeItemsFromCollection(mappings, this.javaTypeDeclarationToJDBCTypeMappings, JAVA_TYPE_DECLARATION_TO_JDBC_TYPE_MAPPINGS_COLLECTION);
+	}
+
+	public void removeJavaTypeDeclarationToJDBCTypeMappings(Iterator<JavaTypeDeclarationToJDBCTypeMapping> mappings) {
+		this.removeItemsFromCollection(mappings, this.javaTypeDeclarationToJDBCTypeMappings, JAVA_TYPE_DECLARATION_TO_JDBC_TYPE_MAPPINGS_COLLECTION);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * @see java.sql.Types
+	 */
+	public JDBCType jdbcTypeForCode(int jdbcTypeCode) {
+		synchronized (this.jdbcTypes) {
+			for (Iterator<JDBCType> stream = this.jdbcTypes.iterator(); stream.hasNext(); ) {
+				JDBCType jdbcType = stream.next();
+				if (jdbcType.getCode() == jdbcTypeCode) {
+					return jdbcType;
+				}
+			}
+			throw new IllegalArgumentException("missing JDBC type for code: " + jdbcTypeCode);
+		}
+	}
+
+	/**
+	 * case sensitive
+	 * @see java.sql.Types
+	 */
+	JDBCType jdbcTypeNamed(String jdbcTypeName) {
+		synchronized (this.jdbcTypes) {
+			for (Iterator<JDBCType> stream = this.jdbcTypes.iterator(); stream.hasNext(); ) {
+				JDBCType jdbcType = stream.next();
+				if (jdbcType.getName().equals(jdbcTypeName)) {
+					return jdbcType;
+				}
+			}
+			throw new IllegalArgumentException("missing JDBC type named: " + jdbcTypeName);
+		}
+	}
+
+	/**
+	 * Returns whether the specified JDBC type has a corresponding
+	 * Java type declaration; this is used for validation
+	 */
+	private boolean jdbcTypeCanBeMappedToJavaTypeDeclaration(JDBCType jdbcType) {
+		synchronized (this.jdbcTypeToJavaTypeDeclarationMappings) {
+			for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings.iterator(); stream.hasNext(); ) {
+				if (stream.next().maps(jdbcType)) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * Returns whether the specified Java type declaration has a corresponding
+	 * JDBC datatype; this can be used to determine whether a
+	 * Java class can be mapped with a direct-to-field mapping
+	 * (or a direct collection mapping), as opposed to needing its
+	 * own descriptor
+	 */
+	boolean javaTypeDeclarationCanBeMappedToJDBCType(String javaClassName, int arrayDepth) {
+		synchronized (this.javaTypeDeclarationToJDBCTypeMappings) {
+			for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings.iterator(); stream.hasNext(); ) {
+				if (stream.next().maps(javaClassName, arrayDepth)) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * Returns the JDBC type for the specified Java type declaration;
+	 * used to generate tables from classes
+	 */
+	JDBCType jdbcTypeForJavaTypeDeclaration(String javaClassName, int arrayDepth) {
+		synchronized (this.javaTypeDeclarationToJDBCTypeMappings) {
+			for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = this.javaTypeDeclarationToJDBCTypeMappings.iterator(); stream.hasNext(); ) {
+				JavaTypeDeclarationToJDBCTypeMapping mapping = stream.next();
+				if (mapping.maps(javaClassName, arrayDepth)) {
+					return mapping.getJDBCType();
+				}
+			}
+			throw new IllegalArgumentException("missing JDBC type mapping for Java type declaration: " + javaClassName + this.brackets(arrayDepth));
+		}
+	}
+
+	/**
+	 * Returns the Java type declaration for the specified JDBC type;
+	 * used to generate classes from tables
+	 */
+	JavaTypeDeclaration javaTypeDeclarationFor(JDBCType jdbcType) {
+		synchronized (this.jdbcTypeToJavaTypeDeclarationMappings) {
+			for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = this.jdbcTypeToJavaTypeDeclarationMappings.iterator(); stream.hasNext(); ) {
+				JDBCTypeToJavaTypeDeclarationMapping mapping = stream.next();
+				if (mapping.maps(jdbcType)) {
+					return mapping.getJavaTypeDeclaration();
+				}
+			}
+			throw new IllegalArgumentException("missing Java type declaration mapping for JDBC type: " + jdbcType);
+		}
+	}
+
+	/**
+	 * Returns the Java type declaration for the specified JDBC type;
+	 * used to generate classes from tables
+	 */
+	JavaTypeDeclaration javaTypeDeclarationForJDBCTypeCode(int jdbcTypeCode) {
+		return this.javaTypeDeclarationFor(this.jdbcTypeForCode(jdbcTypeCode));
+	}
+
+	private Iterator<String> jdbcTypeNames() {
+		return new TransformationIterator<String, JDBCType>(this.jdbcTypes()) {
+			@Override
+			protected String transform(JDBCType next) {
+				return next.getName();
+			}
+		};
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.mappingsmodel.AbstractNodeModel#addChildrenTo(java.util.List)
+	 */
+	@Override
+	protected void addChildrenTo(List<org.eclipse.persistence.tools.utility.node.Node> children) {
+		super.addChildrenTo(children);
+		synchronized (this.jdbcTypes) { children.addAll(this.jdbcTypes); }
+		synchronized (this.jdbcTypeToJavaTypeDeclarationMappings) { children.addAll(this.jdbcTypeToJavaTypeDeclarationMappings); }
+		synchronized (this.javaTypeDeclarationToJDBCTypeMappings) { children.addAll(this.javaTypeDeclarationToJDBCTypeMappings); }
+	}
+
+	/**
+	 * disallow duplicate JDBC type names or codes
+	 */
+	private void checkJDBCType(JDBCType jdbcType) {
+		this.checkJDBCType(jdbcType.getName(), jdbcType.getCode());
+	}
+
+	/**
+	 * disallow duplicate JDBC type names or codes
+	 */
+	private void checkJDBCType(String jdbcTypeName, int jdbcTypeCode) {
+		this.checkJDBCTypeName(jdbcTypeName);
+		this.checkJDBCTypeCode(jdbcTypeCode);
+	}
+
+	/**
+	 * disallow duplicate JDBC type names
+	 */
+	void checkJDBCTypeName(String jdbcTypeName) {
+		if (jdbcTypeName == null) {
+			throw new NullPointerException();
+		}
+		if (CollectionTools.contains(this.jdbcTypeNames(), jdbcTypeName)) {
+			throw new IllegalArgumentException("duplicate JDBC type name: " + jdbcTypeName);
+		}
+	}
+
+	/**
+	 * disallow duplicate JDBC type codes
+	 */
+	void checkJDBCTypeCode(int jdbcTypeCode) {
+		synchronized (this.jdbcTypes) {
+			for (Iterator<JDBCType> stream = this.jdbcTypes.iterator(); stream.hasNext(); ) {
+				if (stream.next().getCode() ==  jdbcTypeCode) {
+					throw new IllegalArgumentException("duplicate JDBC type code: " + jdbcTypeCode);
+				}
+			}
+		}
+	}
+
+	/**
+	 * disallow duplicate JDBC type mappings
+	 */
+	private void checkJDBCToJavaMapping(JDBCType jdbcType) {
+		if (this.jdbcTypeCanBeMappedToJavaTypeDeclaration(jdbcType)) {
+			throw new IllegalArgumentException("duplicate mapping: " + jdbcType.getName());
+		}
+	}
+
+	/**
+	 * disallow duplicate Java type declaration mappings
+	 */
+	private void checkJavaToJDBCMapping(String javaClassName, int arrayDepth) {
+		if (this.javaTypeDeclarationCanBeMappedToJDBCType(javaClassName, arrayDepth)) {
+			throw new IllegalArgumentException("duplicate mapping: " + javaClassName + this.brackets(arrayDepth));
+		}
+	}
+
+	/**
+	 * disallow duplicate Java type declaration mappings
+	 */
+	private void checkJavaToJDBCMapping(JavaTypeDeclaration javaTypeDeclaration) {
+		this.checkJavaToJDBCMapping(javaTypeDeclaration.getJavaClassName(), javaTypeDeclaration.getArrayDepth());
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		if (node == null) {
+			throw new CorruptXMLException("missing node");
+		}
+
+		this.readJDBCTypeNodes(XMLTools.child(node, "jdbc-types"));
+		if (this.jdbcTypes.isEmpty()) {
+			throw new CorruptXMLException("the JDBC type repository is empty");
+		}
+
+		String defaultJDBCTypeName = XMLTools.childTextContent(node, "default-jdbc-type", null);
+		try {
+			this.defaultJDBCType = this.jdbcTypeNamed(defaultJDBCTypeName);
+		} catch (IllegalArgumentException ex) {
+			throw new CorruptXMLException("default JDBC type", ex);
+		}
+
+		this.readJDBCToJavaMappingNodes(XMLTools.child(node, "jdbc-type-to-java-type-declaration-mappings"));
+		// make sure we have mapped ALL the JDBC types (there are no duplicates at this point)
+		if (this.jdbcTypeToJavaTypeDeclarationMappings.size() != this.jdbcTypes.size()) {
+			throw new CorruptXMLException("all the JDBC types must be mapped to Java type declarations");
+		}
+
+		this.readJavaToJDBCMappingNodes(XMLTools.child(node, "java-type-declaration-to-jdbc-type-mappings"));
+	}
+
+	private void readJDBCTypeNodes(Node jdbcTypesNode) throws CorruptXMLException {
+		Node[] jdbcTypeNodes = XMLTools.children(jdbcTypesNode, "jdbc-type");
+		int len = jdbcTypeNodes.length;
+		for (int i = 0; i < len; i++) {
+			JDBCType jdbcType = new JDBCType(this, jdbcTypeNodes[i]);
+			try {
+				this.checkJDBCType(jdbcType);	// check for duplicates
+			} catch (IllegalArgumentException ex) {
+				throw new CorruptXMLException(ex);
+			}
+			this.jdbcTypes.add(jdbcType);
+		}
+	}
+
+	private void readJDBCToJavaMappingNodes(Node mappingsNode) throws CorruptXMLException {
+		Node[] mappingNodes = XMLTools.children(mappingsNode, "jdbc-type-to-java-type-declaration-mapping");
+		int len = mappingNodes.length;
+		for (int i = 0; i < len; i++) {
+			JDBCTypeToJavaTypeDeclarationMapping mapping = new JDBCTypeToJavaTypeDeclarationMapping(this, mappingNodes[i]);
+			try {
+				this.checkJDBCToJavaMapping(mapping.getJDBCType());	// check for duplicates
+			} catch (IllegalArgumentException ex) {
+				throw new CorruptXMLException(ex);
+			}
+			this.jdbcTypeToJavaTypeDeclarationMappings.add(mapping);
+		}
+	}
+
+	private void readJavaToJDBCMappingNodes(Node mappingsNode) throws CorruptXMLException {
+		Node[] mappingNodes = XMLTools.children(mappingsNode, "java-type-declaration-to-jdbc-type-mapping");
+		int len = mappingNodes.length;
+		for (int i = 0; i < len; i++) {
+			JavaTypeDeclarationToJDBCTypeMapping mapping = new JavaTypeDeclarationToJDBCTypeMapping(this, mappingNodes[i]);
+			try {
+				this.checkJavaToJDBCMapping(mapping.getJavaTypeDeclaration());	// check for duplicates
+			} catch (IllegalArgumentException ex) {
+				throw new CorruptXMLException(ex);
+			}
+			this.javaTypeDeclarationToJDBCTypeMappings.add(mapping);
+		}
+	}
+
+	void write(Node node) {
+		Document document = node.getOwnerDocument();
+		XMLTools.addSimpleTextNode(node, "default-jdbc-type", this.defaultJDBCType.getName());
+		this.writeJDBCTypeNodes(node.appendChild(document.createElement("jdbc-types")));
+		this.writeJDBCToJavaMappingNodes(node.appendChild(document.createElement("jdbc-type-to-java-type-declaration-mappings")));
+		this.writeJavaToJDBCMappingNodes(node.appendChild(document.createElement("java-type-declaration-to-jdbc-type-mappings")));
+	}
+
+	private void writeJDBCTypeNodes(Node jdbcTypesNode) {
+		Document document = jdbcTypesNode.getOwnerDocument();
+		synchronized (this.jdbcTypes) {
+			for (Iterator<JDBCType> stream = new TreeSet<JDBCType>(this.jdbcTypes).iterator(); stream.hasNext(); ) {
+				Node jdbcTypeNode = document.createElement("jdbc-type");
+				jdbcTypesNode.appendChild(jdbcTypeNode);
+				stream.next().write(jdbcTypeNode);
+			}
+		}
+	}
+
+	private void writeJDBCToJavaMappingNodes(Node mappingsNode) {
+		Document document = mappingsNode.getOwnerDocument();
+		synchronized (this.jdbcTypeToJavaTypeDeclarationMappings) {
+			for (Iterator<JDBCTypeToJavaTypeDeclarationMapping> stream = new TreeSet<JDBCTypeToJavaTypeDeclarationMapping>(this.jdbcTypeToJavaTypeDeclarationMappings).iterator(); stream.hasNext(); ) {
+				Node mappingNode = document.createElement("jdbc-type-to-java-type-declaration-mapping");
+				mappingsNode.appendChild(mappingNode);
+				stream.next().write(mappingNode);
+			}
+		}
+	}
+
+	private void writeJavaToJDBCMappingNodes(Node mappingsNode) {
+		Document document = mappingsNode.getOwnerDocument();
+		synchronized (this.javaTypeDeclarationToJDBCTypeMappings) {
+			for (Iterator<JavaTypeDeclarationToJDBCTypeMapping> stream = new TreeSet<JavaTypeDeclarationToJDBCTypeMapping>(this.javaTypeDeclarationToJDBCTypeMappings).iterator(); stream.hasNext(); ) {
+				Node mappingNode = document.createElement("java-type-declaration-to-jdbc-type-mapping");
+				mappingsNode.appendChild(mappingNode);
+				stream.next().write(mappingNode);
+			}
+		}
+	}
+
+
+	// ********** printing and displaying **********
+
+	private String brackets(int arrayDepth) {
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < arrayDepth; i++) {
+			sb.append("[]");
+		}
+		return sb.toString();
+	}
+
+	@Override
+	public String displayString() {
+		return StringTools.EMPTY_STRING;
+	}
+
+	public void toString(StringBuffer sb) {
+		sb.append(this.jdbcTypes.size() + " JDBC types");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
new file mode 100644
index 0000000..42f48e5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToDatabaseTypeMapping.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Node;
+
+/**
+ * Map a JDBC type to the appropriate platform-specific database type. Every platform must specify a
+ * database type for every possible JDBC type. The JDBC type cannot be changed.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JDBCTypeToDatabaseTypeMapping extends AbstractNode {
+
+	/** The JDBC type is set upon construction and is immutable. */
+	private JDBCType jdbcType;
+
+	/** The platform-specific database type corresponding to the JDBC type. */
+	private DatabaseType databaseType;
+		public static final String DATABASE_TYPE_PROPERTY = "databaseType";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the mapping is read from an XML file
+	 */
+	JDBCTypeToDatabaseTypeMapping(DatabasePlatform platform, Node node) throws CorruptXMLException {
+		super(platform);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new mapping (which shouldn't happen very often,
+	 * since all the typical mappings have already been built...)
+	 */
+	JDBCTypeToDatabaseTypeMapping(DatabasePlatform platform, JDBCType jdbcType) {
+		super(platform);
+		if (jdbcType == null) {
+			throw new NullPointerException();
+		}
+		this.jdbcType = jdbcType;
+	}
+
+
+	// ********** accessors **********
+
+	private DatabasePlatform getPlatform() {
+		return (DatabasePlatform) this.getParent();
+	}
+
+	public JDBCType getJDBCType() {
+		return this.jdbcType;
+	}
+
+	public DatabaseType getDatabaseType() {
+		return this.databaseType;
+	}
+
+	public void setDatabaseType(DatabaseType databaseType) {
+		Object old = this.databaseType;
+		this.databaseType = databaseType;
+		this.firePropertyChanged(DATABASE_TYPE_PROPERTY, old, databaseType);
+	}
+
+
+	// ********** queries **********
+
+	boolean maps(JDBCType type) {
+		return this.jdbcType == type;
+	}
+
+	boolean maps(int jdbcTypeCode) {
+		return this.jdbcType.getCode() == jdbcTypeCode;
+	}
+
+	private JDBCType jdbcTypeNamed(String jdbcTypeName) {
+		return this.getPlatform().jdbcTypeNamed(jdbcTypeName);
+	}
+
+	private DatabaseType databaseTypeNamed(String databaseTypeName) {
+		return this.getPlatform().databaseTypeNamed(databaseTypeName);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * copy all the settings from the original platform
+	 * to this, newly-created, platform
+	 */
+	void cloneFrom(JDBCTypeToDatabaseTypeMapping originalMapping) {
+		// the jdbcType has been set by the time we get here
+		DatabaseType originalDatabaseType = originalMapping.getDatabaseType();
+		if (originalDatabaseType != null) {
+			this.databaseType = this.databaseTypeNamed(originalDatabaseType.getName());
+		}
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		try {
+			this.jdbcType = this.jdbcTypeNamed(XMLTools.childTextContent(node, "jdbc-type", null));
+		} catch (IllegalArgumentException ex) {
+			throw new CorruptXMLException("platform: " + this.getPlatform().getName(), ex);
+		}
+		String databaseTypeName = XMLTools.childTextContent(node, "database-type", null);
+		if (databaseTypeName != null) {
+			try {
+				this.databaseType = this.databaseTypeNamed(databaseTypeName);
+			} catch (IllegalArgumentException ex) {
+				throw new CorruptXMLException(ex);
+			}
+		}
+	}
+
+	void write(Node node) {
+		XMLTools.addSimpleTextNode(node, "jdbc-type", this.jdbcType.getName());
+		if (this.databaseType != null) {
+			XMLTools.addSimpleTextNode(node, "database-type", this.databaseType.getName());
+		}
+	}
+
+
+	// ********** printing and displaying **********
+
+	private void displayStringOn(StringBuffer sb) {
+		sb.append(this.jdbcType.getName());
+		sb.append(" => ");
+		sb.append(this.databaseType == null ? "null" : this.databaseType.getName());
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		StringBuffer sb = new StringBuffer();
+		this.displayStringOn(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		this.displayStringOn(sb);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java
new file mode 100644
index 0000000..f0dfd75
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JDBCTypeToJavaTypeDeclarationMapping.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.w3c.dom.Node;
+
+/**
+ * Map a JDBC type to the appropriate Java type declaration. These are used to generate classes from
+ * tables. The JDBC type cannot be changed.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JDBCTypeToJavaTypeDeclarationMapping extends AbstractJDBCTypeToJavaTypeDeclarationMapping {
+
+	// the JDBC type can never be replaced once the mapping is built
+	public static final String JAVA_TYPE_DECLARATION_PROPERTY = "javaTypeDeclaration";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the mapping is read from an XML file
+	 */
+	JDBCTypeToJavaTypeDeclarationMapping(JDBCTypeRepository repository, Node node) throws CorruptXMLException {
+		super(repository, node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new mapping (which shouldn't happen very often,
+	 * since all the typical mappings have already been built...)
+	 */
+	JDBCTypeToJavaTypeDeclarationMapping(JDBCTypeRepository repository, JDBCType jdbcType, String javaClassName, int arrayDepth) {
+		super(repository, jdbcType, javaClassName, arrayDepth);
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Set the Java type declaration corresponding to the JDBC type.
+	 */
+	public void setJavaTypeDeclaration(String javaClassName, int arrayDepth) {
+		Object old = this.javaTypeDeclaration;
+		this.javaTypeDeclaration = new JavaTypeDeclaration(this, javaClassName, arrayDepth);
+		this.firePropertyChanged(JAVA_TYPE_DECLARATION_PROPERTY, old, this.javaTypeDeclaration);
+	}
+
+
+	// ********** queries **********
+
+	boolean maps(int jdbcTypeCode) {
+		return this.jdbcType.getCode() == jdbcTypeCode;
+	}
+
+	boolean maps(JDBCType type) {
+		return this.jdbcType == type;
+	}
+
+
+	// ********** i/o **********
+
+	@Override
+	void write(Node node) {
+		this.writeJDBCType(node);
+		this.writeJavaTypeDeclaration(node);
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see AbstractJDBCTypeToJavaTypeDeclarationMapping#displayStringOn(StringBuffer)
+	 */
+	@Override
+	public void displayStringOn(StringBuffer sb) {
+		sb.append(this.jdbcType.getName());
+		sb.append(" => ");
+		this.javaTypeDeclaration.displayStringOn(sb);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java
new file mode 100644
index 0000000..01cb2d8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclaration.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.eclipse.persistence.tools.utility.XMLTools;
+import org.eclipse.persistence.tools.utility.node.AbstractNode;
+import org.w3c.dom.Node;
+
+/**
+ * This class describes a Java type declaration; i.e. a type declaration's
+ * Java class and its array depth. The Java class is referenced by name,
+ * allowing us to reference classes that are not (or cannot be) loaded.
+ *
+ * This class's state is immutable - once an instance is built, its state
+ * cannot be changed. If you want a different declaration, you will need
+ * to build another instance, which isn't all that painful.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JavaTypeDeclaration extends AbstractNode {
+
+	/**
+	 * store the class as a name, so we can reference classes
+	 * that are not loaded
+	 */
+	private String javaClassName;
+
+	/**
+	 * non-array classes have an array depth of zero
+	 */
+	private int arrayDepth;
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the type declaration is read from an XML file
+	 */
+	JavaTypeDeclaration(AbstractNode parent, Node node) throws CorruptXMLException {
+		super(parent);
+		this.read(node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new type declaration
+	 */
+	JavaTypeDeclaration(AbstractNode parent, String javaClassName, int arrayDepth) {
+		super(parent);
+		this.javaClassName = javaClassName;
+		this.arrayDepth = arrayDepth;
+		this.checkState();
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new type declaration with an array depth of zero
+	 */
+	JavaTypeDeclaration(AbstractNode parent, String javaClassName) {
+		this(parent, javaClassName, 0);
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Returns the "element" name of the Java type declaration.
+	 */
+	public String getJavaClassName() {
+		return this.javaClassName;
+	}
+
+	/**
+	 * Returns the "array depth" of the Java type declaration.
+	 */
+	public int getArrayDepth() {
+		return this.arrayDepth;
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * there can be multiple instances of the same Java type
+	 * declaration, so provide some way of comparing them
+	 */
+	boolean equals(String otherJavaClassName, int otherArrayDepth) {
+		return this.javaClassName.equals(otherJavaClassName)
+			&& this.arrayDepth == otherArrayDepth;
+	}
+
+	/**
+	 * there can be multiple instances of the same Java type
+	 * declaration, so provide some way of comparing them
+	 */
+	boolean equals(JavaTypeDeclaration other) {
+		return this.equals(other.javaClassName, other.arrayDepth);
+	}
+
+
+	// ********** behavior **********
+
+	private void checkState() {
+		if ((this.javaClassName == null) || (this.javaClassName.length() == 0)) {
+			throw new IllegalStateException("Java class name is required");
+		}
+
+		if (this.arrayDepth < 0) {
+			throw new IllegalStateException("array depth must be greater than or equal to zero: " + this.arrayDepth);
+		}
+		if (this.javaClassName.equals(void.class.getName()) && (this.arrayDepth != 0)) {
+			throw new IllegalStateException("'void' must have an array depth of zero: " + this.arrayDepth);
+		}
+	}
+
+
+	// ********** i/o **********
+
+	private void read(Node node) throws CorruptXMLException {
+		if (node == null) {
+			throw new CorruptXMLException("missing node");
+		}
+		this.javaClassName = XMLTools.childTextContent(node, "java-class-name", null);
+		this.arrayDepth = XMLTools.childIntContent(node, "array-depth", 0);
+		try {
+			this.checkState();
+		} catch (IllegalStateException ex) {
+			throw new CorruptXMLException("illegal state: " + this, ex);
+		}
+	}
+
+	void write(Node node) {
+		XMLTools.addSimpleTextNode(node, "java-class-name", this.javaClassName);
+		XMLTools.addSimpleTextNode(node, "array-depth", this.arrayDepth, 0);
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
+	 */
+	@Override
+	public String displayString() {
+		StringBuffer sb = new StringBuffer();
+		this.displayStringOn(sb);
+		return sb.toString();
+	}
+
+	public void displayStringOn(StringBuffer sb) {
+		sb.append(this.javaClassName);
+		for (int i = this.arrayDepth; i-- > 0; ) {
+			sb.append("[]");
+		}
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.utility.model.workbench.utility.AbstractModel#toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		this.displayStringOn(sb);
+	}
+
+}
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java
new file mode 100644
index 0000000..74b6c98
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/platformsmodel/JavaTypeDeclarationToJDBCTypeMapping.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.platformsmodel;
+
+import org.w3c.dom.Node;
+
+/**
+ * Map a Java type declaration to the appropriate JDBC type.
+ * These are used to generate tables from classes.
+ * The Java type declaration cannot be changed.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JavaTypeDeclarationToJDBCTypeMapping extends AbstractJDBCTypeToJavaTypeDeclarationMapping {
+
+	// the Java type declaration can never be replaced once the mapping is built
+	public static final String JDBC_TYPE_PROPERTY = "jdbcType";
+
+	// ********** constructors **********
+
+	/**
+	 * this constructor is called when the mapping is read from an XML file
+	 */
+	JavaTypeDeclarationToJDBCTypeMapping(JDBCTypeRepository repository, Node node) throws CorruptXMLException {
+		super(repository, node);
+	}
+
+	/**
+	 * this constructor is called when the user (or a test case)
+	 * creates a new mapping (which shouldn't happen very often,
+	 * since all the typical mappings have already been built...)
+	 */
+	JavaTypeDeclarationToJDBCTypeMapping(JDBCTypeRepository repository, String javaClassName, int arrayDepth, JDBCType jdbcType) {
+		super(repository, jdbcType, javaClassName, arrayDepth);
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Set the JDBC type corresponding to the Java type declaration.
+	 */
+	public void setJDBCType(JDBCType jdbcType) {
+		if (jdbcType == null) {
+			throw new NullPointerException();
+		}
+		Object old = this.jdbcType;
+		this.jdbcType = jdbcType;
+		this.firePropertyChanged(JDBC_TYPE_PROPERTY, old, jdbcType);
+	}
+
+
+	// ********** queries **********
+
+	boolean maps(String javaClassName, int arrayDepth) {
+		return this.javaTypeDeclaration.equals(javaClassName, arrayDepth);
+	}
+
+
+	// ********** i/o **********
+
+	@Override
+	void write(Node node) {
+		this.writeJavaTypeDeclaration(node);
+		this.writeJDBCType(node);
+	}
+
+
+	// ********** printing and displaying **********
+
+	/**
+	 * @see AbstractJDBCTypeToJavaTypeDeclarationMapping#displayStringOn(StringBuffer)
+	 */
+	@Override
+	public void displayStringOn(StringBuffer sb) {
+		this.javaTypeDeclaration.displayStringOn(sb);
+		sb.append(" => ");
+		sb.append(this.jdbcType.getName());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalColumn.java
new file mode 100644
index 0000000..d57eccd
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalColumn.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface describing the meta-data describing a database column.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalTable
+ * @version 2.5
+ */
+public interface ExternalColumn {
+
+	/**
+	 * Returns the JDBC type code for the column's datatype
+	 * (e.g. java.sql.Types.VARCHAR).
+	 */
+	int getJDBCTypeCode();
+
+	/**
+	 * Returns the column's unqualified name.
+	 */
+	String getName();
+
+	/**
+	 * Returns the column's scale. If the column does not have a scale
+	 * Returns zero. Typically a column defined as a decimal numeric
+	 * datatype will have a scale.
+	 */
+	int getScale();
+
+	/**
+	 * Returns the column's size. If the column does not have a size
+	 * Returns zero.
+	 */
+	int getSize();
+
+	/**
+	 * Returns the name of the column's platform-specific datatype
+	 * (e.g. "VARCHAR2").
+	 */
+	String getTypeName();
+
+	/**
+	 * Returns whether the column allows null.
+	 */
+	boolean isNullable();
+
+	/**
+	 * Returns whether the column is part of the table's primary key.
+	 */
+	boolean isPrimaryKey();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabase.java
new file mode 100644
index 0000000..cb1808f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabase.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface for an external database that can be queried for metadata.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalDatabaseFactory
+ * @version 2.5
+ */
+public interface ExternalDatabase {
+
+	/**
+	 * Returns the database's catalog names.
+	 * What connotes a "catalog" is typically platform-dependent.
+	 */
+	String[] getCatalogNames();
+
+	/**
+	 * Returns the database's schema names.
+	 * What connotes a "schema" is typically platform-dependent.
+	 */
+	String[] getSchemaNames();
+
+	/**
+	 * Returns all the database's table descriptions.
+	 * Depending on the implementation and/or runtime configuration, clients
+	 * will use this method or #getTableDescriptions(String, String, String, String[]).
+	 */
+	ExternalTableDescription[] getTableDescriptions();
+
+	/**
+	 * Returns the database's table descriptions corresponding to the specified
+	 * search criteria.
+	 * Depending on the implementation and/or runtime configuration, clients
+	 * will use this method or #getTableDescriptions().
+	 * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
+	 */
+	ExternalTableDescription[] getTableDescriptions(String catalogName, String schemaNamePattern, String tableNamePattern, String[] tableTypeNames);
+
+	/**
+	 * Returns the database's table types.
+	 * What connotes a "table type" is typically platform-dependent.
+	 */
+	String[] getTableTypeNames();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabaseFactory.java
new file mode 100644
index 0000000..7da8d0f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalDatabaseFactory.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+import java.sql.Connection;
+
+/**
+ * Simple factory interface for building external databases.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @version 2.5
+ */
+public interface ExternalDatabaseFactory {
+
+	/**
+	 * Returns an {@link ExternalDatabase} for the specified connection. The connection will be <code>null</code>
+	 * if a connection to a database has not been established or is inappropriate. The connection can
+	 * be ignored, as appropriate.
+	 */
+	ExternalDatabase buildDatabase(Connection connection);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKey.java
new file mode 100644
index 0000000..543cdf2
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKey.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface describing the meta-data describing a database foreign key.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalTable
+ * @version 2.5
+ */
+public interface ExternalForeignKey {
+
+	/**
+	 * Returns an array of the foreign key's column pairs. These pairs match up a foreign key column
+	 * on the source table with a primary key column on the target table.
+	 */
+	ExternalForeignKeyColumnPair[] getColumnPairs();
+
+	/**
+	 * Returns the foreign key's name. Often this name is system-generated.
+	 */
+	String getName();
+
+	/**
+	 * Returns a description of the foreign key's target table.
+	 */
+	ExternalTableDescription getTargetTableDescription();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKeyColumnPair.java
new file mode 100644
index 0000000..e29bb9b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalForeignKeyColumnPair.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface describing the meta-data describing a database foreign key.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalForeignKey
+ * @version 2.5
+ */
+public interface ExternalForeignKeyColumnPair {
+
+	/**
+	 * Returns the "source" half of the column pair. This is the column on the source table that must
+	 * contain a value that matches the value in the target column.
+	 */
+	ExternalColumn getSourceColumn();
+
+	/**
+	 * Returns the "target" half of the column pair. This is typically a column that is part of the
+	 * target table's primary key.
+	 */
+	ExternalColumn getTargetColumn();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTable.java
new file mode 100644
index 0000000..d13f945
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTable.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface defining the table meta-data.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalTableDescription
+ * @version 2.5
+ */
+public interface ExternalTable {
+
+	/**
+	 * Returns an array of the table's columns.
+	 */
+	ExternalColumn[] getColumns();
+
+	/**
+	 * Returns an array of the table's foreign keys.
+	 */
+	ExternalForeignKey[] getForeignKeys();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTableDescription.java
new file mode 100644
index 0000000..4c4d61f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/ExternalTableDescription.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * Interface defining a lightweight wrapper around the database metadata.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @see ExternalDatabase
+ * @version 2.5
+ */
+public interface ExternalTableDescription extends TableDescription {
+
+	/**
+	 * Returns the ExternalTable object corresponding to this {@link ExternalTableDescription} object.
+	 * This allows this <code>ExternalTableDescription</code> to postpone loading extra meta-data
+	 * until it is actually needed. The name and description are required beforehand because they are
+	 * used by the user to select an {@link ExternalTable} to load.
+	 */
+	ExternalTable getTable();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/TableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/TableDescription.java
new file mode 100644
index 0000000..9ba81af
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/TableDescription.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi;
+
+/**
+ * This defines a common interface for all the tables (internal, external, and user-defined)
+ * so they can be consolidated whenever necessary (e.g. in the UI choosers).
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @version 2.5
+ */
+public interface TableDescription {
+
+	/**
+	 * Returns any additional information about the table represented by this <code>TableDescription</code>,
+	 * as a string. This information can be used to differentiate among <code>TableDescription</code>
+	 * objects that might have the same name.
+	 */
+	String getAdditionalInfo();
+
+	/**
+	 * Returns the table's "catalog" name.
+	 */
+	String getCatalogName();
+
+	/**
+	 * Returns the table's unqualified name.
+	 */
+	String getName();
+
+	/**
+	 * Returns the table's fully-qualified name, typically in the form "catalog.schema.name".
+	 */
+	String getQualifiedName();
+
+	/**
+	 * Returns the table's "schema" name.
+	 */
+	String getSchemaName();
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java
new file mode 100644
index 0000000..4b4fb4a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalColumn.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * @see comment about defensive programming at JDBCExternalDatabase
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+final class JDBCExternalColumn implements ExternalColumn {
+	private final String name;
+	private final String typeName;
+	private final int jdbcTypeCode;
+	private final int size;
+	private final int scale;	// used by fixed point numbers only
+	private final boolean nullable;
+	private boolean primaryKey;	// pseudo-final
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct an external column with the data from the current
+	 * row of the specified result set.
+	 * @see java.sql.DatabaseMetaData#getColumns(String, String, String, String)
+	 */
+	JDBCExternalColumn(ResultSet resultSet) throws SQLException {
+		super();
+
+		// the name is required, the other settings can be fudged
+		this.name = resultSet.getString(4).trim();		// COLUMN_NAME
+		if (this.name.length() == 0) {
+			throw new IllegalStateException("empty column name");
+		}
+
+		this.typeName = this.typeNameFrom(resultSet);
+		this.jdbcTypeCode = this.jdbcTypeCodeFrom(resultSet);
+		this.size = this.sizeFrom(resultSet);
+		this.scale = this.scaleFrom(resultSet);
+		this.nullable = this.nullableFrom(resultSet);
+
+		// 'primaryKey' will be set later by the table
+	}
+
+	private String typeNameFrom(ResultSet resultSet) {
+		try {
+			return this.trim(resultSet.getString(6));		// TYPE_NAME
+		} catch (SQLException ex) {
+			// * Returns null if TYPE_NAME is not supported by the driver
+			return null;
+		}
+	}
+
+	private int jdbcTypeCodeFrom(ResultSet resultSet) {
+		try {
+			return resultSet.getInt(5);		// DATA_TYPE
+		} catch (SQLException ex) {
+			// * Returns NULL(?) if DATA_TYPE is not supported by the driver
+			return Types.NULL;
+		}
+	}
+
+	private int sizeFrom(ResultSet resultSet) {
+		try {
+			return resultSet.getInt(7);		// COLUMN_SIZE
+		} catch (SQLException ex) {
+			// * Returns 0 if COLUMN_SIZE is not supported by the driver
+			return 0;
+		}
+	}
+
+	private int scaleFrom(ResultSet resultSet) {
+		try {
+			return resultSet.getInt(9);		// DECIMAL_DIGITS
+		} catch (SQLException ex) {
+			// * Returns 0 if DECIMAL_DIGITS is not supported by the driver
+			return 0;
+		}
+	}
+
+	/**
+	 * use IS_NULLABLE, since NULLABLE is pretty much useless;
+	 * confusing... see the JDK JavaDocs...
+	 */
+	private boolean nullableFrom(ResultSet resultSet) {
+		String jdbc_IS_NULLABLE = null;
+		try {
+			jdbc_IS_NULLABLE = resultSet.getString(18);		// IS_NULLABLE
+		} catch (SQLException ex) {
+			// defensive - continue with 'null' if IS_NULLABLE is not supported by the driver
+		}
+
+		// * Returns fixed-length strings
+		// if this is "NO", the column is *definitely* required (NOT NULL);
+		// * Returns true
+		if ((jdbc_IS_NULLABLE != null) && jdbc_IS_NULLABLE.trim().toUpperCase().equals("NO")) {
+			return false;
+		}
+
+		// NULLABLE (column 11) cannot tell us anything *definite* except that
+		// * Returns true
+		return true;
+	}
+
+	/**
+	 * trim down the specified string, to null if necessary
+	 */
+	private String trim(String s) {
+		if (s == null) {
+			return null;
+		}
+		s = s.trim();
+		return (s.length() == 0) ? null : s;
+	}
+
+
+	// ********** ExternalColumn implementation **********
+
+	/**
+	 * the name should never be null or empty
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalColumn#getName()
+	 */
+	@Override
+	public String getName() {
+		return this.name;
+	}
+
+	/**
+	 * the type name can be null if we have problems reading the result set
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalColumn#getTypeName()
+	 */
+	@Override
+	public String getTypeName() {
+		return this.typeName;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int getJDBCTypeCode() {
+		return this.jdbcTypeCode;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int getSize() {
+		return this.size;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int getScale() {
+		return this.scale;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isNullable() {
+		return this.nullable;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isPrimaryKey() {
+		return this.primaryKey;
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.name);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * the primary key flag is set by the table soon after construction
+	 */
+	void setPrimaryKey(boolean primaryKey) {
+		this.primaryKey = primaryKey;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java
new file mode 100644
index 0000000..0773b47
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabase.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
+import org.eclipse.persistence.tools.utility.CollectionTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+import org.eclipse.persistence.tools.utility.iterators.ResultSetIterator;
+
+/**
+ * This external database derives all of its metadata from a client-supplied JDBC connection.
+ *
+ * All the JDBC implementation classes have an embarassing
+ * preponderance of "defensive" programming that allow us to
+ * work with even the most misbehaved of JDBC drivers. This is
+ * because most of the exceptions encountered are the result
+ * of bugs in the wide variety of JDBC drivers we interact with,
+ * not bugs in Workbench code. (At least that's the hope....)
+ * An alternative to the various bits of defensive programming,
+ * we could pass in a listener whenever there is the possibility
+ * of an (SQL) exception. The listener would be notified of any
+ * exceptions, but we would continue processing with pre-
+ * determined defaults.
+ * ~bjv
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+final class JDBCExternalDatabase implements ExternalDatabase {
+	private final Connection connection;
+	private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+	/**
+	 *
+	 */
+	JDBCExternalDatabase(Connection connection) {
+		super();
+		this.connection = connection;
+	}
+
+
+	// ********** ExternalDatabase implementation **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase#getCatalogNames()
+	 */
+	@Override
+	public String[] getCatalogNames() {
+		ResultSet resultSet;
+		try {
+			resultSet = this.metaData().getCatalogs();
+		} catch (SQLException ex) {
+			return EMPTY_STRING_ARRAY;		// defensive - this is not fatal if unsupported by driver
+		}
+		return this.buildStringArray(resultSet);
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase#getSchemaNames()
+	 */
+	@Override
+	public String[] getSchemaNames() {
+		ResultSet resultSet;
+		try {
+			resultSet = this.metaData().getSchemas();
+		} catch (SQLException ex) {
+			return EMPTY_STRING_ARRAY;		// defensive - this is not fatal if unsupported by driver
+		}
+		return this.buildStringArray(resultSet);
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase#getTableTypeNames()
+	 */
+	@Override
+	public String[] getTableTypeNames() {
+		ResultSet resultSet;
+		try {
+			resultSet = this.metaData().getTableTypes();
+		} catch (SQLException ex) {
+			return EMPTY_STRING_ARRAY;		// defensive - this is not fatal if unsupported by driver
+		}
+		return this.buildStringArray(resultSet);
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase#getTableDescriptions(String, String, String, String[])
+	 */
+	@Override
+	public ExternalTableDescription[] getTableDescriptions(String catalogName, String schemaNamePattern, String tableNamePattern, String[] tableTypeNames) {
+		// #setCatalog(String) is used by Sybase, MS SQL Server, and others(?)
+		// to set a "local context" for later interactions with the server;
+		// "If the driver does not support catalogs, it will silently ignore this request."
+		if (catalogName != null) {
+			try {
+				this.getConnection().setCatalog(catalogName);
+			} catch (SQLException ex) {
+				// see comment above...
+				throw new RuntimeException(ex);
+			}
+		}
+
+		ResultSet resultSet;
+		try {
+			resultSet = this.metaData().getTables(catalogName, schemaNamePattern, tableNamePattern, tableTypeNames);
+		} catch (SQLException ex) {
+			// if #getTables() does not work, there's not much we can do...
+			throw new RuntimeException(ex);
+		}
+		List<ExternalTableDescription> tableDescriptions = CollectionTools.list(new ResultSetIterator<ExternalTableDescription>(
+			resultSet,
+			new ExternalTableDescriptionResultSetAdapter())
+		);
+		return tableDescriptions.toArray(new ExternalTableDescription[tableDescriptions.size()]);
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase#getTableDescriptions()
+	 */
+	@Override
+	public ExternalTableDescription[] getTableDescriptions() {
+		// query for *all* the tables on the database - could be painful...
+		return this.getTableDescriptions(null, null, "%", null);
+	}
+
+
+	// ********** queries **********
+
+	private Connection getConnection() {
+		if (this.connection == null) {
+			throw new IllegalStateException("not connected");
+		}
+		return this.connection;
+	}
+
+	DatabaseMetaData metaData() {
+		try {
+			return this.getConnection().getMetaData();
+		} catch (SQLException ex) {
+			// if we can't get meta-data, there's not much we can do...
+			throw new RuntimeException(ex);
+		}
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * convert the specified single-column result set to an array of strings
+	 */
+	private String[] buildStringArray(ResultSet resultSet) {
+		List<String> strings = CollectionTools.list(new ResultSetIterator<String>(resultSet, new StringResultSetAdapter()));
+		return strings.toArray(new String[strings.size()]);
+	}
+
+
+	// ********** inner classes **********
+
+	/**
+	 * Trim a single-column result set of strings.
+	 */
+	private static class StringResultSetAdapter implements ResultSetIterator.Adapter<String> {
+		@Override
+		public String buildNext(ResultSet rs) throws SQLException {
+			// result set column indexes are 1-based
+			String string = rs.getString(1);
+			// * Returns fixed-length strings
+			return (string == null) ? null : string.trim();
+		}
+	}
+
+	/**
+	 * Convert the rows into external table descriptions.
+	 * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
+	 */
+	private class ExternalTableDescriptionResultSetAdapter implements ResultSetIterator.Adapter<ExternalTableDescription> {
+		@Override
+		public ExternalTableDescription buildNext(ResultSet rs) throws SQLException {
+			return new JDBCExternalTableDescription(rs, JDBCExternalDatabase.this);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java
new file mode 100644
index 0000000..dc560f1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalDatabaseFactory.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.Connection;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabase;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalDatabaseFactory;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * Not much to say here: This is a factory for generating instances of
+ * the "JDBC" implementation of ExternalDatabase, which uses a
+ * java.sql.Connection ExternalTables etc.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+public final class JDBCExternalDatabaseFactory implements ExternalDatabaseFactory {
+
+	/** the singleton */
+	private static ExternalDatabaseFactory INSTANCE;
+
+	/**
+	 * Singleton support.
+	 */
+	public static synchronized ExternalDatabaseFactory instance() {
+		if (INSTANCE == null) {
+			INSTANCE = new JDBCExternalDatabaseFactory();
+		}
+		return INSTANCE;
+	}
+
+	/**
+	 * Private constructor - use the singleton.
+	 */
+	public JDBCExternalDatabaseFactory() {
+		super();
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalDatabaseFactory#buildDatabase(java.sql.Connection)
+	 */
+	@Override
+	public ExternalDatabase buildDatabase(Connection connection) {
+		return new JDBCExternalDatabase(connection);
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, "singleton");
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java
new file mode 100644
index 0000000..67c73d7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKey.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ *
+ * @version 2.5
+ */
+final class JDBCExternalForeignKey implements ExternalForeignKey {
+	private final JDBCExternalTable table;
+	private final String name;
+	private final ExternalTableDescription targetTableDescription;
+	private ExternalForeignKeyColumnPair[] columnPairs;		// pseudo-final
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct a "skeleton" external foreign key with the data from the current
+	 * row of the specified result set. The column pairs will be added later.
+	 * @see java.sql.DatabaseMetaData#getImportedKeys(String, String, String)
+	 */
+	JDBCExternalForeignKey(JDBCExternalTable table, String name, ResultSet resultSet) {
+		super();
+		this.table = table;
+		this.name = name;
+		this.targetTableDescription = new JDBCExternalTableDescription(
+				this.stringFrom(resultSet, 1),		// PKTABLE_CAT
+				this.stringFrom(resultSet, 2),		// PKTABLE_SCHEM
+				this.stringFrom(resultSet, 3),		// PKTABLE_NAME
+				this.database()
+			);
+		// the column pairs will be added by the table, momentarily
+	}
+
+	private String stringFrom(ResultSet resultSet, int colIndex) {
+		try {
+			return this.trim(resultSet.getString(colIndex));
+		} catch (SQLException ex) {
+			// * Returns null if the requested column is not supported by the driver
+			return null;
+		}
+	}
+
+	/**
+	 * trim down the specified string, to null if necessary
+	 */
+	private String trim(String s) {
+		if (s == null) {
+			return null;
+		}
+		s = s.trim();
+		return (s.length() == 0) ? null : s;
+	}
+
+
+	// ********** ExternalForeignKey implementation **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey#getName()
+	 */
+	@Override
+	public String getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey#getColumnPairs()
+	 */
+	@Override
+	public ExternalForeignKeyColumnPair[] getColumnPairs() {
+		return this.columnPairs;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey#getTargetTableDescription()
+	 */
+	@Override
+	public ExternalTableDescription getTargetTableDescription() {
+		return this.targetTableDescription;
+	}
+
+
+	// ********** behavior **********
+
+	void addColumnPair(ResultSet resultSet) {
+		int len = (this.columnPairs == null) ? 0 : this.columnPairs.length;
+		JDBCExternalForeignKeyColumnPair[] temp = new JDBCExternalForeignKeyColumnPair[len + 1];
+		if (len != 0) {
+			System.arraycopy(this.columnPairs, 0, temp, 0, len);
+		}
+		temp[len] = new JDBCExternalForeignKeyColumnPair(this, resultSet);
+		this.columnPairs = temp;
+	}
+
+
+	// ********** queries **********
+
+	JDBCExternalColumn columnNamed(String columnName) {
+		return this.table.columnNamed(columnName);
+	}
+
+	private JDBCExternalDatabase database() {
+		return this.table.database();
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.name);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
new file mode 100644
index 0000000..11ea660
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalForeignKeyColumnPair.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * Associate a pair of columns from a foreign key that is made
+ * up of, possibly, multiple pairs of columns.
+ * Either column can be null if we have any problems gathering
+ * up the meta-data.
+ *
+ * @version 2.5
+ */
+@SuppressWarnings("nls")
+final class JDBCExternalForeignKeyColumnPair implements ExternalForeignKeyColumnPair {
+	private final JDBCExternalForeignKey foreignKey;
+	private final ExternalColumn sourceColumn;
+	private final ExternalColumn targetColumn;
+
+	// ********** constructor/initialization **********
+
+	/**
+	 *
+	 * @see java.sql.DatabaseMetaData#getImportedKeys(String, String, String)
+	 */
+	JDBCExternalForeignKeyColumnPair(JDBCExternalForeignKey foreignKey, ResultSet resultSet) {
+		super();
+		this.foreignKey = foreignKey;
+		this.sourceColumn = this.columnNamed(this.stringFrom(resultSet, 8));		// FKCOLUMN_NAME
+		this.targetColumn = this.buildLocalColumn(this.stringFrom(resultSet, 4));		// PKCOLUMN_NAME
+	}
+
+	private String stringFrom(ResultSet resultSet, int colIndex) {
+		try {
+			return this.trim(resultSet.getString(colIndex));
+		} catch (SQLException ex) {
+			// * Returns null if the requested column is not supported by the driver
+			return null;
+		}
+	}
+
+	/**
+	 * trim down the specified string, to null if necessary
+	 */
+	private String trim(String s) {
+		if (s == null) {
+			return null;
+		}
+		s = s.trim();
+		return (s.length() == 0) ? null : s;
+	}
+
+
+	// ********** ExternalForeignKeyColumnPair implementation **********
+
+	/**
+	 * the source column can be null if we have problems reading the result set
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair#getSourceColumn()
+	 */
+	@Override
+	public ExternalColumn getSourceColumn() {
+		return this.sourceColumn;
+	}
+
+	/**
+	 * the target column can be null if we have problems reading the result set
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKeyColumnPair#getTargetColumn()
+	 */
+	@Override
+	public ExternalColumn getTargetColumn() {
+		return this.targetColumn;
+	}
+
+
+	// ********** queries **********
+
+	private JDBCExternalColumn columnNamed(String columnName) {
+		return this.foreignKey.columnNamed(columnName);
+	}
+
+	private ExternalColumn buildLocalColumn(String columnName) {
+		return (columnName == null) ? null : new TargetColumn(columnName);
+	}
+
+	private String sourceColumnName() {
+		return (this.sourceColumn == null) ? null : this.sourceColumn.getName();
+	}
+
+	private String targetColumnName() {
+		return (this.targetColumn == null) ? null : this.targetColumn.getName();
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.sourceColumnName() + "=>" + this.targetColumnName());
+	}
+
+
+	// ********** member class **********
+
+	/**
+	 * Returns its name;
+	 * all other operations are unsupported
+	 */
+	private static class TargetColumn implements ExternalColumn {
+		private final String name;
+		TargetColumn(String name) {
+			super();
+			if (name == null) {
+				throw new NullPointerException();
+			}
+			this.name = name;
+		}
+		@Override
+		public String getName() {
+			return this.name;
+		}
+		@Override
+		public int getJDBCTypeCode() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public String getTypeName() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public int getSize() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public int getScale() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public boolean isNullable() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public boolean isPrimaryKey() {
+			throw new UnsupportedOperationException();
+		}
+		@Override
+		public String toString() {
+			return StringTools.buildToStringFor(this, this.name);
+		}
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java
new file mode 100644
index 0000000..9dd734b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTable.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalColumn;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalForeignKey;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTable;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * see comment about defensive programming at JDBCExternalDatabase
+ *
+ * @version 2.5
+ */
+final class JDBCExternalTable implements ExternalTable {
+	private final JDBCExternalTableDescription tableDescription;
+	private final JDBCExternalColumn[] columns;
+	private final ExternalForeignKey[] foreignKeys;
+
+	private static final JDBCExternalForeignKey[] EMPTY_FOREIGN_KEYS = new JDBCExternalForeignKey[0];
+
+	// ********** constructor/initialization **********
+
+	/**
+	 *
+	 */
+	JDBCExternalTable(JDBCExternalTableDescription tableDescription) throws SQLException {
+		super();
+		this.tableDescription = tableDescription;
+		this.columns = this.buildColumns();
+		this.markPrimaryKeyColumns();
+		this.foreignKeys = this.buildForeignKeys();
+	}
+
+	/**
+	 * query the database for the table's columns
+	 * @see java.sql.DatabaseMetaData#getColumns(String, String, String, String)
+	 */
+	private JDBCExternalColumn[] buildColumns() throws SQLException {
+		Collection<JDBCExternalColumn> cols = new ArrayList<JDBCExternalColumn>();
+		ResultSet resultSet = this.metaData().getColumns(
+				this.tableDescription.getCatalogName(),
+				this.tableDescription.getSchemaName(),
+				this.tableDescription.getName(),
+				null
+			);
+		while (resultSet.next()) {
+			cols.add(new JDBCExternalColumn(resultSet));
+		}
+		resultSet.close();
+		return cols.toArray(new JDBCExternalColumn[cols.size()]);
+	}
+
+	private void markPrimaryKeyColumns() {
+		Collection<String> pkColNames = this.primaryKeyColumnNames();
+		for (int i = this.columns.length; i-- > 0; ) {
+			JDBCExternalColumn column = this.columns[i];
+			column.setPrimaryKey(pkColNames.contains(column.getName()));
+		}
+	}
+
+	/**
+	 * defensive wrapper
+	 */
+	private Collection<String> primaryKeyColumnNames() {
+		try {
+			return this.primaryKeyColumnNames2();
+		} catch (SQLException ex) {
+			// defensive - this is not fatal if unsupported by driver
+		}
+		return Collections.emptySet();
+	}
+
+	/**
+	 * Returns the names of the table's primary key columns
+	 * @see java.sql.DatabaseMetaData#getPrimaryKeys(String, String, String)
+	 */
+	private Collection<String> primaryKeyColumnNames2() throws SQLException {
+		Collection<String> names = new HashSet<String>();
+		ResultSet resultSet = this.metaData().getPrimaryKeys(
+				this.tableDescription.getCatalogName(),
+				this.tableDescription.getSchemaName(),
+				this.tableDescription.getName()
+			);
+		while (resultSet.next()) {
+			// * Returns fixed-length strings
+			names.add(resultSet.getString(4).trim());		// COLUMN_NAME
+		}
+		resultSet.close();
+		return names;
+	}
+
+	/**
+	 * defensive wrapper
+	 */
+	private JDBCExternalForeignKey[] buildForeignKeys() {
+		try {
+			return this.buildForeignKeys2();
+		} catch (SQLException ex) {
+			// defensive - this is not fatal if unsupported by driver
+		}
+		return EMPTY_FOREIGN_KEYS;
+	}
+
+	/**
+	 * query the database for the table's foreign keys
+	 * @see java.sql.DatabaseMetaData#getImportedKeys(String, String, String)
+	 */
+	private JDBCExternalForeignKey[] buildForeignKeys2() throws SQLException {
+		Collection<JDBCExternalForeignKey> fKeys = new ArrayList<JDBCExternalForeignKey>();
+		ResultSet resultSet = this.metaData().getImportedKeys(
+				this.tableDescription.getCatalogName(),
+				this.tableDescription.getSchemaName(),
+				this.tableDescription.getName()
+			);
+		while (resultSet.next()) {
+			String fKeyName = resultSet.getString(12).trim();		// FK_NAME
+			JDBCExternalForeignKey fKey = this.foreignKeyNamed(fKeyName, fKeys);
+			if (fKey == null) {
+				fKey = new JDBCExternalForeignKey(this, fKeyName, resultSet);
+				fKeys.add(fKey);
+			}
+			fKey.addColumnPair(resultSet);
+		}
+		resultSet.close();
+		return fKeys.toArray(new JDBCExternalForeignKey[fKeys.size()]);
+	}
+
+	/**
+	 * search the specified collection of foreign keys for the foreign
+	 * key with the specified name; assume(?) that foreign keys with
+	 * the same name have the same target table
+	 */
+	private JDBCExternalForeignKey foreignKeyNamed(String fKeyName, Collection<JDBCExternalForeignKey> fKeys) {
+		for (JDBCExternalForeignKey fKey : fKeys) {
+			if (fKey.getName().equals(fKeyName)) {
+				return fKey;
+			}
+		}
+		return null;
+	}
+
+
+	// ********** ExternalTable implementation **********
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ExternalColumn[] getColumns() {
+		return this.columns;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ExternalForeignKey[] getForeignKeys() {
+		return this.foreignKeys;
+	}
+
+
+	// ********** queries **********
+
+	private DatabaseMetaData metaData() {
+		return this.tableDescription.metaData();
+	}
+
+	JDBCExternalDatabase database() {
+		return this.tableDescription.getDatabase();
+	}
+
+	JDBCExternalColumn columnNamed(String columnName) {
+		for (int i = this.columns.length; i-- > 0; ) {
+			JDBCExternalColumn column = this.columns[i];
+			if (column.getName().equals(columnName)) {
+				return column;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.tableDescription.getQualifiedName());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java
new file mode 100644
index 0000000..51831d3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.db/src/org/eclipse/persistence/tools/db/relational/spi/jdbc/JDBCExternalTableDescription.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation from Oracle TopLink
+******************************************************************************/
+package org.eclipse.persistence.tools.db.relational.spi.jdbc;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTable;
+import org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription;
+import org.eclipse.persistence.tools.utility.NameTools;
+import org.eclipse.persistence.tools.utility.StringTools;
+
+/**
+ * @version 2.5
+ */
+final class JDBCExternalTableDescription implements ExternalTableDescription {
+	private final JDBCExternalDatabase database;
+	private final String catalogName;
+	private final String schemaName;
+	private final String name;
+	private final String qualifiedName;	// cache the qualified name, since it will not change
+	private ExternalTable externalTable;		// pseudo-final
+
+
+	// ********** constructor/initialization **********
+
+	/**
+	 * Construct an external table description from the current row
+	 * in the specified result set. The result set corresponds to the
+	 * result set returned from DatabaseMetaData#getTables(String, String, String, String[]).
+	 * @see java.sql.DatabaseMetaData#getTables(String, String, String, String[])
+	 */
+	JDBCExternalTableDescription(ResultSet resultSet, JDBCExternalDatabase database) throws SQLException {
+		this(
+			// * Returns fixed-length strings;
+			// these calls *shouldn't* throw any SQL exceptions...
+			trim(resultSet.getString(1)),		// TABLE_CAT
+			trim(resultSet.getString(2)),		// TABLE_SCHEM
+			trim(resultSet.getString(3)),		// TABLE_NAME
+			database
+		);
+	}
+
+	JDBCExternalTableDescription(String catalogName, String schemaName, String name, JDBCExternalDatabase database) {
+		super();
+		this.catalogName = catalogName;
+		this.schemaName = schemaName;
+		this.name = name;
+		this.qualifiedName = this.buildQualifiedName();
+		this.database = database;
+	}
+
+	/**
+	 * trim down the specified string, to null if necessary
+	 */
+	private static String trim(String s) {
+		if (s == null) {
+			return null;
+		}
+		s = s.trim();
+		return (s.length() == 0) ? null : s;
+	}
+
+	private String buildQualifiedName() {
+		return NameTools.buildQualifiedDatabaseObjectName(this.catalogName, this.schemaName, this.name);
+	}
+
+
+	// ********** ExternalTableDescription implementation **********
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription#getCatalogName()
+	 */
+	@Override
+	public String getCatalogName() {
+		return this.catalogName;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription#getSchemaName()
+	 */
+	@Override
+	public String getSchemaName() {
+		return this.schemaName;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription#getName()
+	 */
+	@Override
+	public String getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription#getQualifiedName()
+	 */
+	@Override
+	public String getQualifiedName() {
+		return this.qualifiedName;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.ExternalTableDescription#getTable()
+	 */
+	@Override
+	public ExternalTable getTable() {
+		if (this.externalTable == null) {
+			this.externalTable = this.buildExternalTable();
+		}
+		return this.externalTable;
+	}
+
+	/**
+	 * @see org.eclipse.persistence.tools.db.relational.spi.TableDescription#getAdditionalInfo()
+	 */
+	@Override
+	public String getAdditionalInfo() {
+		try {
+			return this.metaData().getURL();
+		} catch (SQLException ex) {
+			return null;
+		}
+	}
+
+
+	// ********** behavior **********
+
+	private ExternalTable buildExternalTable() {
+		try {
+			return new JDBCExternalTable(this);
+		} catch (SQLException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+
+	// ********** queries **********
+
+	DatabaseMetaData metaData() {
+		return this.database.metaData();
+	}
+
+	JDBCExternalDatabase getDatabase() {
+		return this.database;
+	}
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.qualifiedName);
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms.dpr b/tools/org.eclipse.persistence.tools.db/src/platforms.dpr
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms.dpr
rename to tools/org.eclipse.persistence.tools.db/src/platforms.dpr
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/attunity.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/attunity.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/attunity.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/attunity.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/cloudscape.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/cloudscape.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/cloudscape.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/cloudscape.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/db2.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/db2.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/db2.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/db2.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/dbase.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/dbase.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/dbase.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/dbase.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/derby.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/derby.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/derby.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/derby.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/hsql.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/hsql.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/hsql.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/hsql.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/informix.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/informix.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/informix.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/informix.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/javadb.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/javadb.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/javadb.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/javadb.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/msaccess.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/msaccess.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/msaccess.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/msaccess.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/mysql.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/mysql.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/mysql.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/mysql.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/mysql4.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/mysql4.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/mysql4.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/mysql4.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/oracle.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/oracle.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle10g.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/oracle10g.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle10g.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/oracle10g.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle11.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/oracle11.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle11.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/oracle11.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle8i.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/oracle8i.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle8i.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/oracle8i.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle9i.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/oracle9i.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/oracle9i.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/oracle9i.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/other.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/other.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/other.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/other.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/pointbase.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/pointbase.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/pointbase.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/pointbase.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/postgresql.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/postgresql.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/postgresql.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/postgresql.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/sqlanywhere.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/sqlanywhere.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/sqlanywhere.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/sqlanywhere.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/sqlserver.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/sqlserver.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/sqlserver.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/sqlserver.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/sybase.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/sybase.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/sybase.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/sybase.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/timesten.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/timesten.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/timesten.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/timesten.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/src/platforms/timesten7.xml b/tools/org.eclipse.persistence.tools.db/src/platforms/timesten7.xml
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen.db/src/platforms/timesten7.xml
rename to tools/org.eclipse.persistence.tools.db/src/platforms/timesten7.xml
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.classpath b/tools/org.eclipse.persistence.tools.gen.db/.classpath
index 0b9079a..32c7e58 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/.classpath
+++ b/tools/org.eclipse.persistence.tools.gen.db/.classpath
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="resource/templates/xml_entities"/>
+	<classpathentry kind="src" path="resource/property_files"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
 		<attributes>
 			<attribute name="owner.project.facets" value="java"/>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.component b/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.component
index fe564e6..771a706 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.component
+++ b/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.component
@@ -2,5 +2,7 @@
 <project-modules id="moduleCoreId" project-version="1.5.0">
     <wb-module deploy-name="org.eclipse.persistence.tools.gen.db">
         <wb-resource deploy-path="/" source-path="/src"/>
+        <wb-resource deploy-path="/" source-path="/resource/templates/xml_entities"/>
+        <wb-resource deploy-path="/" source-path="/resource/property_files"/>
     </wb-module>
 </project-modules>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.project.facet.core.xml b/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.project.facet.core.xml
index fd68f7e..2d6935f 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <faceted-project>
-  <fixed facet="java"/>
   <fixed facet="jst.utility"/>
-  <installed facet="java" version="1.6"/>
+  <fixed facet="java"/>
   <installed facet="jst.utility" version="1.0"/>
+  <installed facet="java" version="1.6"/>
 </faceted-project>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.gen.db/META-INF/MANIFEST.MF
index 8c08d4e..39549bc 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/META-INF/MANIFEST.MF
+++ b/tools/org.eclipse.persistence.tools.gen.db/META-INF/MANIFEST.MF
@@ -1,19 +1,16 @@
 Manifest-Version: 1.0
-Export-Package: org.eclipse.persistence.tools.db,
- org.eclipse.persistence.tools.db.driver,
- org.eclipse.persistence.tools.db.model,
- org.eclipse.persistence.tools.db.model.handles,
- org.eclipse.persistence.tools.db.model.platformsmodel,
- org.eclipse.persistence.tools.db.model.spi,
- org.eclipse.persistence.tools.db.model.spi.jdbc,
- platforms
+Export-Package: org.eclipse.persistence.tools.gen,
+ org.eclipse.persistence.tools.gen.db,
+ org.eclipse.persistence.tools.gen.internal,
+ org.eclipse.persistence.tools.gen.internal.util
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Require-Bundle: org.eclipse.persistence.tools.utility;bundle-version="2.5.0",
- org.eclipse.persistence.tools.gen;bundle-version="2.5.0",
- org.eclipse.persistence.core;bundle-version="2.4.0"
+Require-Bundle: org.apache.velocity;bundle-version="1.5.0",
+ org.apache.commons.collections;bundle-version="3.2.0",
+ org.jdom;bundle-version="1.1.1",
+ org.apache.commons.lang;bundle-version="2.1.0",
+ org.eclipse.persistence.tools.utility;bundle-version="2.5.0"
 Bundle-SymbolicName: org.eclipse.persistence.tools.gen.db
-Bundle-Name: EclipseLink Tools Db
+Bundle-Name: EclipseLink Tools Gen
 Bundle-Vendor: Eclipse.org - EclipseLink Project
 Bundle-Version: 2.5.0.qualifier
 Bundle-ManifestVersion: 2
-Import-Package: org.w3c.dom;resolution:=optional
diff --git a/tools/org.eclipse.persistence.tools.gen.db/build.properties b/tools/org.eclipse.persistence.tools.gen.db/build.properties
index b107977..4cc0ed9 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/build.properties
+++ b/tools/org.eclipse.persistence.tools.gen.db/build.properties
@@ -1,3 +1,5 @@
-source.. = src/
+source.. = src/,\
+           resource/templates/xml_entities/,\
+           resource/property_files/
 bin.includes = META-INF/,\
                .
diff --git a/tools/org.eclipse.persistence.tools.gen.db/pom.xml b/tools/org.eclipse.persistence.tools.gen.db/pom.xml
index 3e72258..96af76b 100644
--- a/tools/org.eclipse.persistence.tools.gen.db/pom.xml
+++ b/tools/org.eclipse.persistence.tools.gen.db/pom.xml
@@ -3,7 +3,7 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <modelVersion>4.0.0</modelVersion>
 
-    <name>EclipseLink Tools Gen DB</name>
+    <name>EclipseLink Tools Gen</name>
     <groupId>org.eclipse.persistence</groupId>
     <artifactId>org.eclipse.persistence.tools.gen.db</artifactId>
     <version>2.5.0-SNAPSHOT</version>
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/property_files/jpt_gen.properties b/tools/org.eclipse.persistence.tools.gen.db/resource/property_files/jpt_gen.properties
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/property_files/jpt_gen.properties
rename to tools/org.eclipse.persistence.tools.gen.db/resource/property_files/jpt_gen.properties
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/basic.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/basic.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/basic.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/basic.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/column.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/column.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/column.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/column.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/embeddable.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/embeddable.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/embeddable.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/embeddable.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/embeddedBasic.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/embeddedBasic.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/embeddedBasic.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/embeddedBasic.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/footer.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/footer.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/footer.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/footer.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/header.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/header.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/header.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/id.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/id.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/id.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/id.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/join.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/join.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/join.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/join.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/main.xml.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/main.xml.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/main.xml.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/manyToMany.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/manyToMany.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/manyToMany.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/manyToMany.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/manyToOne.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/manyToOne.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/manyToOne.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/manyToOne.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/namedQuery.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/namedQuery.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/namedQuery.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/namedQuery.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/oneToMany.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/oneToMany.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/oneToMany.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/oneToMany.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/version.vm b/tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/version.vm
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/resource/templates/xml_entities/version.vm
rename to tools/org.eclipse.persistence.tools.gen.db/resource/templates/xml_entities/version.vm
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/DatabaseType.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/DatabaseType.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/DatabaseType.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/DatabaseType.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/DynamicEntityGenerator.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/DynamicEntityGenerator.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/DynamicEntityGenerator.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/DynamicEntityGenerator.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Catalog.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Catalog.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Catalog.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Catalog.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Column.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Column.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Column.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Column.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionAdapter.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionListener.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionListener.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionListener.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionListener.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfile.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileAdapter.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileAdapter.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileAdapter.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileAdapter.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileFactory.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileFactory.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileFactory.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileFactory.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileListener.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileListener.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileListener.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ConnectionProfileListener.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Database.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Database.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Database.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Database.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseIdentifierAdapter.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/DatabaseObject.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ForeignKey.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ForeignKey.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/ForeignKey.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/ForeignKey.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Schema.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Schema.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Schema.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Schema.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/SchemaContainer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/SchemaContainer.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/SchemaContainer.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/SchemaContainer.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Sequence.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Sequence.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Sequence.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Sequence.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Table.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Table.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/db/Table.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/db/Table.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/Association.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/Association.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/Association.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/AssociationRole.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/BaseEntityGenCustomizer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/BaseEntityGenCustomizer.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/BaseEntityGenCustomizer.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/BaseEntityGenCustomizer.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/DatabaseAnnotationNameBuilder.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/EntityGeneratorDatabaseAnnotationNameBuilder.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/EntityGeneratorDatabaseAnnotationNameBuilder.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/EntityGeneratorDatabaseAnnotationNameBuilder.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/EntityGeneratorDatabaseAnnotationNameBuilder.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/GenericEntityGeneratorDatabaseAnnotationNameBuilder.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/GenericEntityGeneratorDatabaseAnnotationNameBuilder.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/GenericEntityGeneratorDatabaseAnnotationNameBuilder.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/GenericEntityGeneratorDatabaseAnnotationNameBuilder.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/JptGenMessages.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/MappingFileGenerator.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenColumn.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenColumn.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenColumn.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenColumn.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenCustomizer.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenTable.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenTable.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/ORMGenTable.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/ORMGenTable.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/OverwriteConfirmer.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/TagNames.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/TagNames.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/TagNames.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/TagNames.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/EntityGenTools.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/FileUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/FileUtil.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/FileUtil.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/FileUtil.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/ForeignKeyInfo.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/ForeignKeyInfo.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/ForeignKeyInfo.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/ForeignKeyInfo.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/StringUtil.java
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java b/tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
similarity index 100%
rename from tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
rename to tools/org.eclipse.persistence.tools.gen.db/src/org/eclipse/persistence/tools/gen/internal/util/UrlUtil.java
diff --git a/tools/org.eclipse.persistence.tools.gen/.classpath b/tools/org.eclipse.persistence.tools.gen.nosql/.classpath
similarity index 78%
copy from tools/org.eclipse.persistence.tools.gen/.classpath
copy to tools/org.eclipse.persistence.tools.gen.nosql/.classpath
index 32c7e58..0b9079a 100644
--- a/tools/org.eclipse.persistence.tools.gen/.classpath
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/.classpath
@@ -1,8 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="resource/templates/xml_entities"/>
-	<classpathentry kind="src" path="resource/property_files"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
 		<attributes>
 			<attribute name="owner.project.facets" value="java"/>
diff --git a/tools/org.eclipse.persistence.tools.gen/.project b/tools/org.eclipse.persistence.tools.gen.nosql/.project
similarity index 94%
copy from tools/org.eclipse.persistence.tools.gen/.project
copy to tools/org.eclipse.persistence.tools.gen.nosql/.project
index 831ed03..fdfea59 100644
--- a/tools/org.eclipse.persistence.tools.gen/.project
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>org.eclipse.persistence.tools.gen</name>
+	<name>org.eclipse.persistence.tools.gen.nosql</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.resources.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.core.resources.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.resources.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.core.resources.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.runtime.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.core.runtime.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.core.runtime.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.core.runtime.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.jdt.core.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.jdt.core.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.jdt.core.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.jdt.core.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.ltk.core.refactoring.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.ltk.core.refactoring.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.ltk.core.refactoring.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.ltk.core.refactoring.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.component b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..fe564e6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-modules id="moduleCoreId" project-version="1.5.0">
+    <wb-module deploy-name="org.eclipse.persistence.tools.gen.db">
+        <wb-resource deploy-path="/" source-path="/src"/>
+    </wb-module>
+</project-modules>
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.project.facet.core.xml
similarity index 99%
copy from tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.project.facet.core.xml
index 2d6935f..fd68f7e 100644
--- a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <faceted-project>
-  <fixed facet="jst.utility"/>
   <fixed facet="java"/>
-  <installed facet="jst.utility" version="1.0"/>
+  <fixed facet="jst.utility"/>
   <installed facet="java" version="1.6"/>
+  <installed facet="jst.utility" version="1.0"/>
 </faceted-project>
diff --git a/tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.xsl.core.prefs b/tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.xsl.core.prefs
similarity index 100%
copy from tools/org.eclipse.persistence.tools.gen.db/.settings/org.eclipse.wst.xsl.core.prefs
copy to tools/org.eclipse.persistence.tools.gen.nosql/.settings/org.eclipse.wst.xsl.core.prefs
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.gen.nosql/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..df4abe3
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Export-Package: 
+ org.eclipse.persistence.tools.gen.nosql.mongo
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.persistence.tools.utility;bundle-version="2.5.0",
+ org.eclipse.persistence.tools.mapping;bundle-version="2.5.0"
+Bundle-SymbolicName: org.eclipse.persistence.tools.gen.nosql
+Bundle-Name: EclipseLink Tools NoSql
+Bundle-Vendor: Eclipse.org - EclipseLink Project
+Bundle-Version: 2.5.0.qualifier
+Bundle-ManifestVersion: 2
+Import-Package: com.mongodb;resolution:=optional,
+ org.bson;resolution:=optional
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/build.properties b/tools/org.eclipse.persistence.tools.gen.nosql/build.properties
new file mode 100644
index 0000000..b107977
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/build.properties
@@ -0,0 +1,3 @@
+source.. = src/
+bin.includes = META-INF/,\
+               .
diff --git a/tools/org.eclipse.persistence.tools.gen/pom.xml b/tools/org.eclipse.persistence.tools.gen.nosql/pom.xml
similarity index 86%
rename from tools/org.eclipse.persistence.tools.gen/pom.xml
rename to tools/org.eclipse.persistence.tools.gen.nosql/pom.xml
index ffc11fc..7b47290 100644
--- a/tools/org.eclipse.persistence.tools.gen/pom.xml
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/pom.xml
@@ -3,9 +3,9 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <modelVersion>4.0.0</modelVersion>
 
-    <name>EclipseLink Tools Gen</name>
+    <name>EclipseLink Tools Gen DB</name>
     <groupId>org.eclipse.persistence</groupId>
-    <artifactId>org.eclipse.persistence.tools.gen</artifactId>
+    <artifactId>org.eclipse.persistence.tools.gen.nosql</artifactId>
     <version>2.5.0-SNAPSHOT</version>
     <packaging>eclipse-plugin</packaging>
 
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/META-INF/persistence.xml b/tools/org.eclipse.persistence.tools.gen.nosql/src/META-INF/persistence.xml
new file mode 100644
index 0000000..92e3288
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/META-INF/persistence.xml
@@ -0,0 +1,14 @@
+<persistence-unit name="mongo-example" transaction-type="RESOURCE_LOCAL">
+		<provider>
+            org.eclipse.persistence.jpa.PersistenceProvider
+        </provider>
+		<mapping-file>META-INF/test.xml</mapping-file>
+		<properties>
+            <property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"/>
+            <property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"/>
+            <property name="eclipselink.nosql.property.mongo.port" value="27017"/>
+            <property name="eclipselink.nosql.property.mongo.host" value="localhost"/>
+            <property name="eclipselink.nosql.property.mongo.db" value="scratch"/>
+            <property name="eclipselink.logging.level" value="FINEST"/>
+        </properties>
+</persistence-unit>
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoDynamicEntityGenerator.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoDynamicEntityGenerator.java
new file mode 100644
index 0000000..6288e14
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoDynamicEntityGenerator.java
@@ -0,0 +1,431 @@
+package org.eclipse.persistence.tools.gen.nosql.mongo;
+
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.persistence.tools.gen.nosql.mongo.meta.CollectionDescriptor;
+import org.eclipse.persistence.tools.gen.nosql.mongo.meta.ColumnDescriptor;
+import org.eclipse.persistence.tools.gen.nosql.mongo.meta.LeafColumnDescriptor;
+import org.eclipse.persistence.tools.gen.nosql.mongo.meta.NestedColumnDescriptor;
+import org.eclipse.persistence.tools.mapping.orm.DataFormatType;
+import org.eclipse.persistence.tools.mapping.orm.ExternalColumnMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddableEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalNamedQuery;
+import org.eclipse.persistence.tools.mapping.orm.ExternalNoSql;
+import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
+import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
+import org.eclipse.persistence.tools.mapping.orm.dom.ORMRepository;
+import org.eclipse.persistence.tools.utility.NameTools;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.ServerAddress;
+
+/**
+ * This class is an entry point for dynamic entity generation for MongoDB. 
+ * It provides API for discovering metadata (table names, etc) and generating 
+ * EclipseLink JPA, NoSql, mapping files.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *
+ * @author John Bracken
+ * @version 2.5
+ */
+public class MongoDynamicEntityGenerator {
+
+	/** Mongo database connection to use in generation. */
+	private Mongo connection;
+	
+	/** Mongo database instance to use in generation. */
+	private DB database;
+	
+	/** Number of rows in each collection to sample during generation. */
+	private int rowSampleSize;
+	
+	/**
+	 * Constructs a new {@link MongoDynamicEntityGenerator} based on the provided 
+	 * db connection information.
+	 * 
+	 * @param host the MongoDB network host.
+	 * @param port the port of the Mongo database.
+	 * @param dbName the name of the Mongo database.
+	 * @param rowSampleSize number of rows in each collection to sample to determine the 
+	 * 		  table structure.  Since not all rows may have all possible values explicitly
+	 * 		  defined, it's important to use a sufficient sample size.
+	 * 
+	 * @throws MongoException
+	 * @throws UnknownHostException
+	 */
+	public MongoDynamicEntityGenerator(String host, int port, String dbName, int rowSampleSize) 
+														throws MongoException, UnknownHostException {
+		super();
+		this.rowSampleSize = rowSampleSize;
+		this.connection = new Mongo(new ServerAddress(host, port));
+		this.database = this.connection.getDB(dbName);
+	}
+
+	/**
+	 * Builds a list of {@link CollectionDescriptor}s that describe the collection and associated
+	 * column metadata of the Mongo collections named in <code>collectionNames</code>.
+	 *  
+	 * @param collectionNames names of the Mongo collections to build descriptors for.
+	 * 
+	 * @return {@link List} of {@link CollectionDescriptor}s.
+	 */
+	private List<CollectionDescriptor> buildCollectionDescriptors(Collection<String> collectionNames) {
+		List<CollectionDescriptor> collectionDescriptors = new LinkedList<CollectionDescriptor>();
+		
+		for (String collectionName : collectionNames) {
+			CollectionDescriptor collectionDescriptor = new CollectionDescriptor(collectionName);
+			collectionDescriptors.add(collectionDescriptor);
+			updateColumnDescriptors(collectionDescriptor);
+		}
+		
+		return collectionDescriptors;
+	}
+	
+	/**
+	 * Updates the {@link CollectionDescriptor}s associated with the provided 
+	 * {@link CollectionDescriptor}.
+	 * 
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 */
+	private void updateColumnDescriptors(CollectionDescriptor collectionDescriptor) {
+		// Read the collection from the database
+		DBCollection collection = this.database.getCollection(collectionDescriptor.getName());
+		
+		// Read a sampling of the rows to determine the super set of column keys
+		// that are in the collection.  
+		DBCursor cursor = collection.find().limit(this.rowSampleSize);
+		for ( ;cursor.hasNext();) {
+			DBObject row = cursor.next();
+			updateCollectionDescriptor(collectionDescriptor, row);
+		}
+
+	}
+	
+	/**
+	 * Creates an eclipselink-orm.xml descriptor mapping the provided <code>collectionNames</code>
+	 * as EclipseLink dynamic entities.
+	 * 
+	 * @param collectionNames
+	 * @return a {@link String} representation of the eclipselink-orm.xml.
+	 */
+	public String generate(Collection<String> collectionNames) {
+		// Create metadata descriptors for the specified collections.
+		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
+		
+		// Generate an eclpselink-orm.xml from the collection descriptors
+		return generateORMConfig(collectionDescriptors);
+	}
+	
+	/**
+	 * Generates and adds to the specified entity a mapping for the leaf mapping described by the 
+	 * {@link CollectionDescriptor}.
+	 * 
+	 * @param exEntity entity to add the mapping to.
+	 * @param column the column to generate the mapping from.
+	 * @param columnName the name of the column.
+	 * @param javaColumnName the java identifier name to use for the column.
+	 */
+	private void generateLeafMapping(ExternalEmbeddableEntity exEntity, LeafColumnDescriptor column, 
+															  String columnName, String javaColumnName) {
+		ExternalColumnMapping mapping;
+		// If this is a list-type column, then a collection based mapping is required.
+		if (column.isList()) {
+			mapping = exEntity.addElementCollectionMapping(columnName);
+			((ExternalElementCollectionMapping)mapping).
+				setTargetClassName(column.getColumnType().getName());
+			mapping.setAttributeType(Vector.class.getName());
+		} else {
+			// special case where _id is reserved as a pk name in mongo.  
+			// this is always intended to be an ID mapping.
+			if (columnName.equals("_id")) {
+				mapping = exEntity.addIdMapping(javaColumnName);
+			} else {
+				mapping = exEntity.addBasicMapping(javaColumnName);
+			}
+			mapping.setAttributeType(column.getColumnType().getName());
+		}
+		mapping.setNoSqlField(columnName);
+	}
+
+	/**
+	 * Generates mappings for the provided mapped class ({@link ExternalEmbeddableEntity}) based on
+	 * the columns enumerated in the provided {@link CollectionDescriptor}.
+	 * 
+	 * @param exEntity the entity to generate mappings on.
+	 * @param collection the Mongo DB collection descriptor to derive rows from.
+	 * @param config the orm configuration.
+	 * @param allEntityNames a {@link Set} of all of the entity names already in use.
+	 */
+	private void generateMappings(ExternalEmbeddableEntity exEntity, CollectionDescriptor collection, 
+														   ExternalORMConfiguration config, Set<String> allEntityNames) {
+		for (ColumnDescriptor column : collection.columns()) {
+			String columnName = column.getColumnName();
+			String javaColumnName = NameTools.javaNameFromDatabaseName(columnName);
+			if (column instanceof LeafColumnDescriptor) {
+				generateLeafMapping(exEntity, (LeafColumnDescriptor)column, 
+									columnName, javaColumnName);
+			} else if (column instanceof NestedColumnDescriptor) {
+				generateNestedMapping(exEntity, config, allEntityNames, 
+									  (NestedColumnDescriptor)column, columnName, javaColumnName);
+			}
+		}
+	}
+
+	/**
+	 * Generates a mapping on the provided mapped class that represents the nested mapping. This will
+	 * also involved generating an {@link Embeddable} to represent the nested value.
+	 * 
+	 * @param exEntity the entity to generate the mapping on.
+	 * @param config the {@link ExternalORMConfiguration} that the entity is associated with.
+	 * @param allEntityNames the existing used namespace for all mapped classes.
+	 * @param column the nested column to generate the mapping for.
+	 * @param columnName the name of the column.
+	 * @param javaColumnName the java identifier name for the column.
+	 */
+	private void generateNestedMapping(ExternalEmbeddableEntity exEntity,ExternalORMConfiguration config, 
+									   Set<String> allEntityNames, NestedColumnDescriptor column, String columnName, String javaColumnName) {
+		// Create the embeddable for the nested value
+		String embeddableName = NameTools.javaNameFromDatabaseName(columnName, true);
+		embeddableName = NameTools.uniqueNameFor(embeddableName, allEntityNames);
+		allEntityNames.add(embeddableName);
+		ExternalEmbeddableEntity embeddable = config.addEmbeddableEntity(embeddableName);
+		embeddable.addNoSql().setDataFormat(DataFormatType.MAPPED);
+		embeddable.setAccessType("VIRTUAL");
+		// generate mappings for the embeddable
+		generateMappings(embeddable, column.getColumnDescriptor(), config, allEntityNames);
+		
+		// if a collection, generate an Element Collection
+		if (column.isList()) {
+			ExternalElementCollectionMapping mapping = exEntity.addElementCollectionMapping(javaColumnName);
+			mapping.setNoSqlField(columnName);
+			mapping.setAttributeType(Vector.class.getName());
+			mapping.setTargetClassName(embeddableName);
+		} 
+		// otherwise, just an embedded mapping.
+		else {
+			ExternalEmbeddedMapping mapping = exEntity.addEmbeddedMapping(javaColumnName);
+			mapping.setNoSqlField(columnName);
+			mapping.setAttributeType(embeddableName);
+		}
+	}
+
+	/**
+	 * Generates a {@link String} representation of an eclipselink-orm.xml descriptor based
+	 * on the provided MongoDB {@link CollectionDescriptor} definitions.  
+	 * 
+	 * @param collectionDescriptors the MongoDB collections to generate entities from.
+	 * 
+	 * @return a {@link String} representation of the eclipselink-orm.xml.
+	 */
+	private String generateORMConfig(List<CollectionDescriptor> collectionDescriptors) {
+		// Create a new orm.xml metadata model.
+		ExternalORMConfiguration config = new ORMRepository().buildORMConfiguration(ORMDocumentType.ECLIPELINK_2_4);
+		// track all entity names being used.
+		Set<String> allEntityNames = new HashSet<String>();
+		// Iterate over all collection descriptors and create an entity and associated mapping for them.
+		for (CollectionDescriptor collection : collectionDescriptors) {
+			// add an entity with a unique name
+			String collectionName = collection.getName();
+			String entityName = NameTools.javaNameFromDatabaseName(collectionName, true);
+			entityName = NameTools.uniqueNameFor(entityName, allEntityNames);
+			allEntityNames.add(entityName);
+			ExternalEntity exEntity = config.addEntity(entityName);
+			// access type is virtual
+			exEntity.setAccessType("VIRTUAL");
+			// Configure NoSql settings
+			ExternalNoSql noSqlDesc = exEntity.addNoSql();
+			noSqlDesc.setDataFormat(DataFormatType.MAPPED);
+			noSqlDesc.setDataType(collectionName);
+			// add mappings
+			generateMappings(exEntity, collection, config, allEntityNames);
+		}
+		
+		// Generate a default, read all query for all entities
+		generateQueries(config);		
+		
+		return config.getXML();
+	}
+	
+	/**
+	 * Generates and adds a root level named query for each entity
+	 * enumerate in the {@link ExternalORMConfiguration}.
+	 * 
+	 * @param config the configuration to generate and add queries from.
+	 */
+	private void generateQueries(ExternalORMConfiguration config) {
+		for (ExternalEntity entity : config.entities()) {
+			String entityName = entity.getClassName();
+			ExternalNamedQuery query = config.addNamedQuery(entityName + ".findAll");
+			char identifier = Character.toLowerCase(entityName.charAt(0));
+			query.setQuery("select " + identifier + " from " + entityName + " "  + identifier);
+			
+		}
+	}
+
+	/**
+	 * Updates the give {@link CollectionDescriptor} with the leaf column information defined
+	 * by row value.
+	 * 
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 * @param columnName the name of the column.
+	 * @param value the row value of the column.
+	 */
+	private void handleLeafColumn(CollectionDescriptor collectionDescriptor,
+													   String columnName, Object value) {
+		LeafColumnDescriptor columnDescriptor = (LeafColumnDescriptor)collectionDescriptor.getColumn(columnName);
+		if (columnDescriptor == null) {
+			columnDescriptor = collectionDescriptor.addLeafColumn(columnName);
+		}
+		Class<?> valueClass = value.getClass();
+		// Special case for an id-type column. If one is not explicitly defined,
+		// Mongo auto-generates one and uses the noted class for the type. This 
+		// should be considered a String in java.
+		valueClass = valueClass.getName().equals("org.bson.types.ObjectId") ? String.class : valueClass;
+		// if the column type isn't consistent, just use Object as the type.
+		if (columnDescriptor.getColumnType() == null) {
+			columnDescriptor.setColumnType(valueClass);
+		} else if (columnDescriptor.getColumnType() != valueClass) {
+			columnDescriptor.setColumnType(Object.class);
+		}
+	}
+
+	/**
+	 * Updates the given {@link CollectionDescriptor} with the a column representing 
+	 * the list-type value.
+	 * 
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 * @param columnName the name of the column to update.
+	 * @param value the row value, or in this case the list value row.
+	 */
+	private void handleListColumn(CollectionDescriptor collectionDescriptor, String columnName, 
+																		    	Object value) {
+		ColumnDescriptor columnDescriptor = collectionDescriptor.getColumn(columnName);
+		BasicDBList listValue = (BasicDBList)value;
+		if (listValue.size() > 0) {
+			Iterator<?> listValues = listValue.listIterator();
+			Object valueFromList = listValues.next();
+			// Handle nested list
+			if (valueFromList instanceof BasicDBObject) {
+				NestedColumnDescriptor nestedColumnDesc;
+				if (columnDescriptor == null) {
+					nestedColumnDesc  = collectionDescriptor.addNestedColumn(columnName);
+				} else { 
+					nestedColumnDesc = (NestedColumnDescriptor)columnDescriptor;
+				}
+				nestedColumnDesc.setList(true);
+				updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject)valueFromList);
+				// Iterate over subsequent nested values to ensure the superset of all columns keys
+				// are included
+				for (;listValues.hasNext();) {
+					valueFromList = listValues.next();
+					updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject)valueFromList);
+				}
+								
+			} 
+			// Handle leaf list
+			else {
+				LeafColumnDescriptor leafColumnDescriptor;
+				if (columnDescriptor == null) {
+					leafColumnDescriptor  = collectionDescriptor.addLeafColumn(columnName);
+				} else { 
+					leafColumnDescriptor = (LeafColumnDescriptor)columnDescriptor;
+				}
+				
+				leafColumnDescriptor.setList(true);
+				leafColumnDescriptor.setColumnType(valueFromList.getClass());
+				// Iterate over subsequent elements. If the element type isn't the same as the last, default to Object
+				// and break.
+				for (;listValues.hasNext();) {
+					valueFromList = listValues.next();
+					if (leafColumnDescriptor.getColumnType() != valueFromList.getClass()) {
+						leafColumnDescriptor.setColumnType(Object.class);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Updates the given {@link CollectionDescriptor} with the nested column information
+	 * derived from the provided row value.
+	 * 
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 * @param columnName name of the column.
+	 * @param value row value of the column, or in this case the nest row.
+	 */
+	private void handleNestedColumn(CollectionDescriptor collectionDescriptor,
+								   					   String columnName, Object value) {
+		NestedColumnDescriptor columnDescriptor = 
+				(NestedColumnDescriptor)collectionDescriptor.getColumn(columnName);
+		
+		if (columnDescriptor == null) {
+			columnDescriptor = collectionDescriptor.addNestedColumn(columnName);
+		}
+		
+		updateCollectionDescriptor(columnDescriptor.getColumnDescriptor(), (DBObject)value);
+	}
+
+	/**
+	 * Updates the given {@link CollectionDescriptor} with columns implied by the provided row 
+	 * or {@link DBObject}.
+	 * 
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 * @param dbObject the row to infer columns from.
+	 */
+	private void updateCollectionDescriptor(CollectionDescriptor collectionDescriptor, DBObject dbObject) {
+		// iterate over all of the available names in the row.
+		for (String columnName : dbObject.keySet()) {
+			Object value = dbObject.get(columnName);
+			// if a column does not yet exist in our descriptor, add one.
+			if (value != null) {
+				// List type
+				if (value instanceof BasicDBList) {
+					handleListColumn(collectionDescriptor, columnName, value);
+				} 
+				// Single Nested
+				else if (value instanceof BasicDBObject) {
+					handleNestedColumn(collectionDescriptor, columnName, value);
+				} 
+				// Leaf Value
+				else {
+					handleLeafColumn(collectionDescriptor, columnName, value);
+				}
+			}
+		}
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/CollectionDescriptor.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/CollectionDescriptor.java
new file mode 100644
index 0000000..0609267
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/CollectionDescriptor.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.gen.nosql.mongo.meta;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Metadata class that describes a NoSql table which may also be referred
+ * to as a Collection or Map depending on the database type.  
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ * 
+ * @author John Bracken
+ * @version 2.5
+ */
+public final class CollectionDescriptor {
+	
+	/** Column descriptors associated with this collection */
+	private Map<String, ColumnDescriptor> columnDescriptors;
+	
+	/** Name of this collection. */
+	private String name;
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param name name of the Mondgo collection
+	 */
+	public CollectionDescriptor(String name) {
+		super();
+		this.name = name;
+		this.columnDescriptors = new HashMap<String, ColumnDescriptor>();
+	}
+	
+	/**
+	 * Adds a new {@link LeafColumnDescriptor} with the provided name.
+	 * 
+	 * @param name name of the column to add.
+	 * @return the new {@link LeafColumnDescriptor}.
+	 */
+	public LeafColumnDescriptor addLeafColumn(String name) {
+		LeafColumnDescriptor column = new LeafColumnDescriptor(name);
+		this.columnDescriptors.put(name, column);
+		
+		return column;
+	}
+
+	/**
+	 * Adds a new {@link NestedColumnDescriptor} with the provided name.
+	 * 
+	 * @param name name of the column to add.
+	 * @return the new {@link NestedColumnDescriptor}.
+	 */
+	public NestedColumnDescriptor addNestedColumn(String name) {
+		NestedColumnDescriptor column = new NestedColumnDescriptor(name);
+		this.columnDescriptors.put(name, column);
+		
+		return column;
+	}
+
+	/**
+	 * Returns the {@link ColumnDescriptor}s associated with this
+	 * collection.
+	 * 
+	 * @return the {@link CollectionDescriptor}s associated with 
+	 * this collection.
+	 */
+	public Iterable<? extends ColumnDescriptor> columns() {
+		return this.columnDescriptors.values();
+	}
+
+	
+	/**
+	 * Returns the {@link ColumnDescriptor} with the given name.
+	 * 
+	 * @param name the name of the {@link ColumnDescriptor}.
+	 * @return the {@link ColumnDescriptor}.
+	 */
+	public ColumnDescriptor getColumn(String name) {
+		return this.columnDescriptors.get(name);
+	}
+	
+	/**
+	 * Returns the name of the Mongo collection represented by
+	 * this descriptor.
+	 * 
+	 * @return the name of this collection descriptor.
+	 */
+	public String getName() {
+		return this.name;
+	}
+	
+	/**
+	 * Removes the provided {@link ColumnDescriptor} from this 
+	 * collection.
+	 * 
+	 * @param columnDescriptor the column descriptor associated with 
+	 * this collection.
+	 */
+	public void removeColumn(ColumnDescriptor columnDescriptor) {
+		this.columnDescriptors.remove(columnDescriptor.getColumnName());
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/ColumnDescriptor.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/ColumnDescriptor.java
new file mode 100644
index 0000000..a74777a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/ColumnDescriptor.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.gen.nosql.mongo.meta;
+
+/**
+ * This class describes the metadata of an abstract representation of a MongoDB 
+ * column.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ * 
+ * @author John Bracken
+ * @version 2.5
+ */
+public abstract class ColumnDescriptor {
+	
+	/** Name of the column */
+	private String columnName;
+	
+	/** Defines whether this column is a list type */ 
+	private boolean isList;
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param columName name of the column.
+	 */
+	public ColumnDescriptor(String columName) {
+		super();
+		this.columnName = columName;
+	}
+	
+	/**
+	 * Returns the name of the column.
+	 * 
+	 * @return the name of the column.
+	 */
+	public String getColumnName() {
+		return columnName;
+	}
+	
+	/**
+	 * Indicates whether this column is a list
+	 * type (e.g. has multiple elements in it's value).
+	 * 
+	 * @return whether this column is a list.
+	 */
+	public boolean isList() {
+		return this.isList;
+	}
+	
+	/**
+	 * Sets whether this column is a list
+	 * type (e.g. has multiple elements in it's value).
+	 * 
+	 * @param isList is this column a list type.
+	 */
+	public void setList(boolean isList) {
+		this.isList = isList;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/LeafColumnDescriptor.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/LeafColumnDescriptor.java
new file mode 100644
index 0000000..84c6c36
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/LeafColumnDescriptor.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.gen.nosql.mongo.meta;
+
+/**
+ * This class describes the metadata of MongoDB column that is a leaf 
+ * value (non-nested).
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *  
+ * @author John Bracken
+ * @version 2.5
+ */
+public final class LeafColumnDescriptor extends ColumnDescriptor {
+
+	/** The type of the column. */
+	private Class<?> columnType;
+	
+	/**
+	 * Constructor. 
+	 * 
+	 * @param columName name of the column.
+	 */
+	public LeafColumnDescriptor(String columName) {
+		super(columName);
+	}
+	
+	/**
+	 * Returns the Java type of the column.
+	 * 
+	 * @return the Java type of the column.
+	 */
+	public Class<?> getColumnType() {
+		return this.columnType;
+	}
+
+	/**
+	 * Sets the Java type of the column.
+	 * 
+	 * @param columnType the Java type of the column.
+	 */
+	public void setColumnType(Class<?> columnType) {
+		this.columnType = columnType;
+	}
+}
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/NestedColumnDescriptor.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/NestedColumnDescriptor.java
new file mode 100644
index 0000000..1a4fd3b
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/meta/NestedColumnDescriptor.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.gen.nosql.mongo.meta;
+
+/**
+ * This class describes the metadata of MongoDB column that is a nested
+ * value (non-nested).  A nested value is a column where the value metadata
+ * can be described by a {@link CollectionDescriptor}.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.<p>
+ *  
+ * @author John Bracken
+ * @version 2.5
+ */
+public final class NestedColumnDescriptor extends ColumnDescriptor{
+
+	/** The column descriptor that describes this columns value. */
+	private CollectionDescriptor columnDescriptor;
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param columName name of the column.
+	 */
+	public NestedColumnDescriptor(String columName) {
+		super(columName);
+		this.columnDescriptor = new CollectionDescriptor(columName);
+	}
+	
+	/**
+	 * The column descriptor that describe the structure of
+	 * this column's nested value. 
+	 */
+	public CollectionDescriptor getColumnDescriptor() {
+		return this.columnDescriptor;
+	}	
+}
diff --git a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.component b/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index 88616f2..0000000
--- a/tools/org.eclipse.persistence.tools.gen/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project-modules id="moduleCoreId" project-version="1.5.0">
-    <wb-module deploy-name="org.eclipse.persistence.tools.gen">
-        <wb-resource deploy-path="/" source-path="/src"/>
-        <wb-resource deploy-path="/" source-path="/resource/templates/xml_entities"/>
-        <wb-resource deploy-path="/" source-path="/resource/property_files"/>
-    </wb-module>
-</project-modules>
diff --git a/tools/org.eclipse.persistence.tools.gen/META-INF/MANIFEST.MF b/tools/org.eclipse.persistence.tools.gen/META-INF/MANIFEST.MF
deleted file mode 100644
index 5c532f8..0000000
--- a/tools/org.eclipse.persistence.tools.gen/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,16 +0,0 @@
-Manifest-Version: 1.0
-Export-Package: org.eclipse.persistence.tools.gen,
- org.eclipse.persistence.tools.gen.db,
- org.eclipse.persistence.tools.gen.internal,
- org.eclipse.persistence.tools.gen.internal.util
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Require-Bundle: org.apache.velocity;bundle-version="1.5.0",
- org.apache.commons.collections;bundle-version="3.2.0",
- org.jdom;bundle-version="1.1.1",
- org.apache.commons.lang;bundle-version="2.1.0",
- org.eclipse.persistence.tools.utility;bundle-version="2.5.0"
-Bundle-SymbolicName: org.eclipse.persistence.tools.gen
-Bundle-Name: EclipseLink Tools Gen
-Bundle-Vendor: Eclipse.org - EclipseLink Project
-Bundle-Version: 2.5.0.qualifier
-Bundle-ManifestVersion: 2
diff --git a/tools/org.eclipse.persistence.tools.gen/build.properties b/tools/org.eclipse.persistence.tools.gen/build.properties
deleted file mode 100644
index 4cc0ed9..0000000
--- a/tools/org.eclipse.persistence.tools.gen/build.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-source.. = src/,\
-           resource/templates/xml_entities/,\
-           resource/property_files/
-bin.includes = META-INF/,\
-               .
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/NoSqlType.java b/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/NoSqlType.java
deleted file mode 100644
index 0bf647a..0000000
--- a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/NoSqlType.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
- * which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- *
- ******************************************************************************/
-package org.eclipse.persistence.tools.gen;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This enumeration defines the NoSQL data source type supported by dynamic entity generation.
- * <p>
- * Provisional API: This interface is part of an interim API that is still under development and
- * expected to change significantly before reaching stability. It is available at this early stage
- * to solicit feedback from pioneering adopters on the understanding that any code that uses this
- * API will almost certainly be broken (repeatedly) as the API evolves.<p>
- *
- * @version 2.5
- */
-@SuppressWarnings("nls")
-public enum NoSqlType {
-
-	/**
-	 * The constant for Mongo database driver.
-	 */
-	Mongo("Mongo", "com.mongodb.Mongo");
-
-	/**
-	 * The fully qualified class name of the driver.
-	 */
-	private String driver;
-
-	/**
-	 * Database type identifier.
-	 */
-	private String typeName;
-
-	/**
-	 * Creates a new <code>NoSqlType</code>.
-	 */
-	private NoSqlType(String typeName, String driver) {
-		this.typeName = typeName;
-		this.driver = driver;
-	}
-
-	/**
-	 * Returns the list of all NoSQL databases.
-	 *
-	 * @return The list of unique constants
-	 */
-	public static Iterable<NoSqlType> types() {
-		List<NoSqlType> types = new ArrayList<NoSqlType>();
-		types.add(Mongo);
-		return types;
-	}
-
-	/**
-	 * Retrieves the enumeration constant for the given value. If the value is not known, then
-	 * <code>null</code> will be returned.
-	 *
-	 * @param value The value to retrieve its constant version
-	 * @return The constant version of the given value
-	 */
-	public static NoSqlType value(String value) {
-		for (NoSqlType type : values()) {
-			if (type.typeName.equals(value)) {
-				return type;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the driver class specific to this NoSQL type.
-	 *
-	 * @return The driver class for this database type
-	 */
-	public String getDatabaseDriver() {
-		return driver;
-	}
-
-	/**
-	 * Returns the type name of the NoSQL database.
-	 *
-	 * @return The name of the NoSQL database
-	 */
-	public String getName() {
-		return this.typeName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String toString() {
-		return this.typeName;
-	}
-}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java~HEAD b/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java~HEAD
deleted file mode 100644
index 385569c..0000000
--- a/tools/org.eclipse.persistence.tools.gen/src/org/eclipse/persistence/tools/gen/internal/util/DBUtil.java~HEAD
+++ /dev/null
@@ -1,80 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2011 Oracle. 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:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.jpa.gen.internal.util;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jpt.jpa.db.Column;
-import org.eclipse.jpt.jpa.db.ForeignKey;
-import org.eclipse.jpt.jpa.db.Schema;
-import org.eclipse.jpt.jpa.db.Table;
-import org.eclipse.jpt.jpa.db.ForeignKey.ColumnPair;
-
-/**
- * Collection of utility methods to access DTP and other jpt.db APIs 
- *
- */
-public class DBUtil {
-
-	public static boolean isAutoIncrement(Column c){
-		//@ TODO
-		//Blocked by DTP bug
-		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=250023
-		//The Dali bug is
-		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=249658
-		//
-		return false;
-	}
-
-	/**
-	 * Return list of fk
-	 * @param dbTable
-	 * @return
-	 */
-	public static List<ForeignKeyInfo> getForeignKeys(Table dbTable) {
-		List<ForeignKeyInfo> ret = new ArrayList<ForeignKeyInfo>();
-		if(dbTable!=null){
-			for (ForeignKey fk : dbTable.getForeignKeys()) {
-				Iterator<ColumnPair> columnPaires = fk.getColumnPairs().iterator();
-				ForeignKeyInfo fkInfo = null;
-				while( columnPaires.hasNext() ){
-					ColumnPair columnPair = columnPaires.next();
-					if( fkInfo == null){
-						String tableName = dbTable.getName();
-						String referencedTableName = "";
-						Table referencedTable = fk.getReferencedTable();
-						referencedTableName = referencedTable.getName();
-						fkInfo = new ForeignKeyInfo(fk, tableName, referencedTableName );
-					}
-					String baseColName = columnPair.getBaseColumn().getName();
-					String referencedColName = columnPair.getReferencedColumn().getName();
-					fkInfo.addColumnMapping( baseColName,  referencedColName );
-				} 
-				if( fkInfo !=null )
-					ret.add( fkInfo );
-			}
-		}
-		return ret;
-	}
-
-	public static String getJavaType(Column dbColumn) {
-		return dbColumn.isPartOfPrimaryKey() ?
-				dbColumn.getPrimaryKeyJavaTypeDeclaration() :
-				dbColumn.getJavaTypeDeclaration();
-	}
-
-	public static boolean isDefaultSchema(Table dbTable){
-		String schemaName = dbTable.getSchema().getName();
-		Schema defaultSchema = dbTable.getSchema().getDatabase().getDefaultSchema();
-		return defaultSchema.getName() == schemaName;
-	}	
-}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
index 3697794..5f1b434 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddableEntity.java
@@ -77,9 +77,15 @@
 	/**
 	 * Adds an embeddable mapping with the given name.
 	 */
-	ExternalMapping addEmbeddedMapping(String name);
+	ExternalEmbeddedMapping addEmbeddedMapping(String name);
 
 	/**
+	 * Adds an id mapping with the given name.
+	 */
+	ExternalIDMapping addIdMapping(String name);
+
+	
+	/**
 	 * Adds instantiation copy policy to this entity
 	 */
 	ExternalInstantiationCopyPolicy addInstantiationCopyPolicy();
@@ -150,9 +156,9 @@
 	ExternalAccessMethods getAccessMethods();
 
 	/**
-	 * Returns the {@link AccessType} to be used in this entity.
+	 * Returns the to be used in this entity.
 	 */
-	AccessType getAccessType();
+	String getAccessType();
 
 	/**
 	 * Returns the change tracking type for this entity
@@ -331,9 +337,10 @@
 	void removeTypeConverter(int index);
 
 	/**
-	 * Sets the {@link AccessType} to be used for this entity.
+	 * Sets the {@link AccessType} to be used for this entity. String
+	 * value used to support "VIRTUAL".
 	 */
-	void setAccessType(AccessType type);
+	void setAccessType(String type);
 
 	/**
 	 * Sets the change tracking type for this entity.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
index 82ecfa5..48469a3 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappedSuperClassEntity.java
@@ -52,11 +52,6 @@
 	ExternalFetchGroup addFetchGroup(int index, String name);
 
 	/**
-	 * Adds an id mapping with the given name.
-	 */
-	ExternalIDMapping addIdMapping(String name);
-
-	/**
 	 * Adds multitenancy
 	 */
 	ExternalMultitenancyPolicy addMultitenancy();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
index 6c9da81..beebe9c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalORMConfiguration.java
@@ -40,6 +40,11 @@
 	 * Adds a new converter.
 	 */
 	ExternalConverter addConverter(int index);
+	
+	/**
+	 * Adds a embedded entity with the given name.
+	 */
+	ExternalEmbeddableEntity addEmbeddableEntity(String embeddableClassName);
 
 	/**
 	 * Adds a embedded entity with the given name.
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
index 884dcf7..5a54028 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddableEntity.java
@@ -16,7 +16,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import javax.persistence.AccessType;
+
 import org.eclipse.persistence.annotations.ChangeTrackingType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicCollectionMapping;
@@ -27,6 +27,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalCopyPolicy;
 import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddableEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalIDMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalInstantiationCopyPolicy;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
@@ -213,7 +214,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final ExternalMapping addEmbeddedMapping(String name) {
+	public final ExternalEmbeddedMapping addEmbeddedMapping(String name) {
 		EmbeddedMapping mapping = buildEmbeddedMapping(mappingsSize());
 		mapping.addSelf();
 		mapping.setName(name);
@@ -221,6 +222,18 @@
 	}
 
 	/**
+	 * Embeddables don't currently support ID, but the implementation
+	 * is here for convenience.
+	 * 
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ExternalIDMapping addIdMapping(String name) {
+		throw new UnsupportedOperationException();
+	}
+		
+		
+	/**
 	 * {@inheritDoc}
 	 */
 	@Override
@@ -580,8 +593,8 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final AccessType getAccessType() {
-		return getEnumAttribute(ACCESS, AccessType.class);
+	public final String getAccessType() {
+		return getAttribute(ACCESS);
 	}
 
 	/**
@@ -1045,7 +1058,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final void setAccessType(AccessType type) {
+	public final void setAccessType(String type) {
 		setAttribute(ACCESS, type);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
index 2c550af..831859f 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
@@ -272,7 +272,6 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	@SuppressWarnings("null")
 	public void setColumn(String columnName) {
 
 		AbstractColumn column = getColumn();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
index dd60604..9db77d7 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ORMConfiguration.java
@@ -134,6 +134,18 @@
 		entity.addSelf();
 		entity.setClassName(className);
 	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ExternalEmbeddableEntity addEmbeddableEntity(String className) {
+		EmbeddableEntity entity = buildEmbeddableEntity(embeddableEntitiesSize());
+		entity.addSelf();
+		entity.setClassName(className);
+		
+		return entity;
+	}
 
 	/**
 	 * {@inheritDoc}
diff --git a/tools/org.eclipse.persistence.tools.parent/pom.xml b/tools/org.eclipse.persistence.tools.parent/pom.xml
index faec476..98c88f8 100644
--- a/tools/org.eclipse.persistence.tools.parent/pom.xml
+++ b/tools/org.eclipse.persistence.tools.parent/pom.xml
@@ -38,9 +38,10 @@
 
     <modules>
         <module>../org.eclipse.persistence.tools.utility</module>
-        <module>../org.eclipse.persistence.tools.gen</module>
+        <module>../org.eclipse.persistence.tools.db</module>
         <module>../org.eclipse.persistence.tools.gen.db</module>
         <module>../org.eclipse.persistence.tools.mapping</module>
+        <module>../org.eclipse.persistence.tools.gen.nosql</module>
         <!-- module>../org.eclipse.persistence.tools.utility.tests</module -->
     </modules>
 
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
index 9f7703e..82c8d81 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/NameTools.java
@@ -19,6 +19,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.SortedSet;
+import java.util.regex.Pattern;
 
 import org.eclipse.persistence.tools.utility.iterators.ArrayIterator;
 
@@ -128,6 +129,9 @@
 		return sb.toString();
 	}
 
+	/** regex used to replace characters in a database identifier that are invalid in java identifiers */
+	private static final Pattern DB_IDENTIFIER_EXCLUSIONS = Pattern.compile("[@$# .]");
+	
 	/**
 	 * The set of reserved words in the Java programming language.
 	 * These words cannot be used as identifiers (i.e. names).
@@ -198,6 +202,36 @@
 		Collections.unmodifiableSortedSet(CollectionTools.sortedSet(JAVA_RESERVED_WORDS));
 
 	/**
+	 * Generates a Java identifier name based on the provided database name.
+	 * Camel-cases the Java identifier on _ characters and on characters that
+	 * are valid in DB identifiers but not Java identifiers (the @ symbol, for
+	 * example). Does not capitalize the first letter of the generated
+	 * identifier.
+	 *
+	 * @param databaseName - <code>String</code> representing the database
+	 * identifier that should be used to produce a Java identifier.
+	 */
+	public static String javaNameFromDatabaseName(String databaseName) {
+		return javaNameFromDatabaseName(databaseName, false);
+	}
+
+	/**
+	 * Generates a Java identifier name based on the provided database name.
+	 * Camel-cases the Java identifier on _ characters and on characters that are
+	 * valid in DB identifiers but not Java identifiers (the @ symbol, for
+	 * example).
+	 * @param databaseName - <code>String</code> representing the database
+	 * identifier that should be used to produce a Java identifier.
+	 *
+	 * @param capitalizeFirstLetter - <code>boolean</code> indicating whether
+	 * the first letter of the identifier should be capitalized.
+	 */
+	public static String javaNameFromDatabaseName(String databaseName, boolean capitalizeFirstLetter) {
+		return StringTools.convertAllCapsToCamelBack(normalizeJavaIdentifier(DB_IDENTIFIER_EXCLUSIONS.matcher(databaseName).replaceAll("_")),
+		capitalizeFirstLetter);
+	}
+	
+	/**
 	 * Returns the set of Java programming language reserved words.
 	 * These words cannot be used as identifiers (i.e. names).
 	 * http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
@@ -207,6 +241,42 @@
 	}
 
 	/**
+	 * Normalizes the specified candidate string as a valid Java identifier.
+	 * Defaults the delimitor character for replacement as '_'.
+	 *
+	 * @see StringTools#normalizeJavaIdentifier(String, char)
+	 */
+	public static String normalizeJavaIdentifier(String candidateString)
+	{
+		return normalizeJavaIdentifier(candidateString, '_');
+	}
+
+	/**
+	 * Normalizes the specified candidate string as a valid Java identifier
+	 * by replacing any invalid characters with the specified delimitor
+	 * character.
+	 */
+	public static String normalizeJavaIdentifier(String candidateString, char delimitor)
+	{
+		StringBuffer normalizedString = new StringBuffer();
+		for(int i=0; i<candidateString.length(); i++)
+		{
+			char currentChar = candidateString.charAt(i);
+			if ((i==0 && Character.isJavaIdentifierStart(currentChar)) ||
+			    Character.isJavaIdentifierPart(currentChar))
+			{
+				normalizedString.append(currentChar);
+			}
+			else
+			{
+				normalizedString.append(delimitor);
+			}
+		}
+
+		return normalizedString.toString();
+	}
+	
+	/**
 	 * Returns whether the specified string consists of Java identifier
 	 * characters (but may be a reserved word).
 	 */
diff --git a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
index c56f258..6462f73 100644
--- a/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
+++ b/tools/org.eclipse.persistence.tools.utility/src/org/eclipse/persistence/tools/utility/StringTools.java
@@ -4284,6 +4284,53 @@
 		return string.equals(string.toLowerCase());
 	}
 
+	// ********** convert all caps to cable back **********
+	
+	/**
+	 * Convert the specified "all caps" string to a "camel back" string:
+	 * "LARGE_PROJECT" -> "largeProject"
+	 * Optionally capitalize the first letter.
+	 */
+	public static String convertAllCapsToCamelBack(String allCapsString, boolean capitalizeFirstLetter) {
+		return convertAllCapsToCamelBack(allCapsString, '_', capitalizeFirstLetter);
+	}
+
+	/**
+	 * Convert the specified "all caps" string to a "camel back" string:
+	 * "LARGE_PROJECT" -> "largeProject"
+	 * Optionally capitalize the first letter.
+	 */
+	public static String convertAllCapsToCamelBack(String allCapsString, char delimitor, boolean capitalizeFirstLetter) {
+		int len = allCapsString.length();
+		if (len == 0) {
+			return EMPTY_STRING;
+		}
+		char prev = 0;
+		char c = 0;
+		StringBuilder sb = new StringBuilder(len);
+		for (int i = 0; i < len; i++) {	// NB: start at 1
+			prev = c;
+			c = allCapsString.charAt(i);
+			if (c == delimitor) {
+				continue;
+			}
+			if (sb.length() == 0) {
+				if (capitalizeFirstLetter) {
+					sb.append(Character.toUpperCase(c));
+				} else {
+					sb.append(Character.toLowerCase(c));
+				}
+			} else {
+				if (prev == delimitor) {
+					sb.append(Character.toUpperCase(c));
+				} else {
+					sb.append(Character.toLowerCase(c));
+				}
+			}
+		}
+		return sb.toString();
+	}
+
 
 	// ********** convert camel case to all caps **********